From 8d76237e821d68a5468074ea3adf8d4d27e2ac74 Mon Sep 17 00:00:00 2001 From: Constantine Date: Sat, 26 Aug 2023 13:10:12 -0700 Subject: [PATCH] dynamic maintenance (#6) * Vertex now mutable and inherits from Vector3d. Generisize to Tuple3d * shuffle responsibilities, firm up api * moar * clean vertex seperation * insert point near given vertex * calculate max step of a delta change in a vertex's position remove tail recursion from star visit * interim * add sturm root isolator * update readme * locate from last * finally clean up graphics ;0 --- README.md | 11 +- .../com/hellblazer/delaunay/Examples.java | 194 - .../com/hellblazer/delaunay/Geometry.java | 152 +- .../delaunay/Tetrahedralization.java | 153 +- .../com/hellblazer/delaunay/Tetrahedron.java | 249 +- .../java/com/hellblazer/delaunay/Vertex.java | 191 +- .../delaunay/sturm/ExpInterval.java | 48 + .../hellblazer/delaunay/sturm/Interval.java | 13 + .../hellblazer/delaunay/sturm/Polynomial.java | 39 + .../delaunay/sturm/SturmRootIsolator.java | 291 ++ .../com/hellblazer/delaunay/Examples.java | 196 + .../hellblazer/delaunay/TestTimeInsert.java | 32 +- .../com/hellblazer/delaunay/TestVertex.java | 38 - .../delaunay/TetrahedralizationTest.java | 60 +- .../com/hellblazer/delaunay/VertexTest.java | 75 + .../delaunay/sturm/RootIsolatorTest.java | 48 + .../hellblazer/delaunay/gui/Constants.java | 35 - .../hellblazer/delaunay/gui/CubicGrid.java | 268 -- .../hellblazer/delaunay/gui/Inspector.java | 58 - .../delaunay/gui/LinkInspector.java | 48 - .../com/hellblazer/delaunay/gui/LinkView.java | 40 - .../delaunay/gui/OrientedFaceInspector.java | 51 - .../delaunay/gui/OrientedFaceView.java | 81 - .../delaunay/gui/PhiCoordinates.java | 287 -- .../hellblazer/delaunay/gui/PointModel.java | 118 - .../{delaunay => voronoi3d}/gui/Colors.java | 2 +- .../gui/GraphicsView.java | 48 +- .../hellblazer/voronoi3d/gui/TestCases.java | 196 + .../gui/TetrahedralizationInspector.java | 267 ++ .../gui/TetrahedralizationView.java | 44 +- .../voronoi3d/gui}/Xform.java | 465 ++- .../hellblazer/voronoi3d/gui}/mesh/Edge.java | 2 +- .../hellblazer/voronoi3d/gui}/mesh/Face.java | 2 +- .../hellblazer/voronoi3d/gui}/mesh/Line.java | 2 +- .../hellblazer/voronoi3d/gui}/mesh/Mesh.java | 2 +- .../voronoi3d/gui}/mesh/PolyLine.java | 2 +- .../exporters/fxml/FXMLExporter.java | 357 -- .../javasource/JavaSourceExporter.java | 528 --- .../height2normal/Height2NormalApp.java | 244 -- .../height2normal/Height2NormalConverter.java | 118 - .../experiments/importers/Importer.java | 78 - .../experiments/importers/Importer3D.java | 172 - .../experiments/importers/ImporterFinder.java | 76 - .../experiments/importers/Optimizer.java | 566 --- .../importers/SmoothingGroups.java | 353 -- .../experiments/importers/Validator.java | 119 - .../importers/dae/DaeImporter.java | 570 --- .../importers/max/MaxAseParser.java | 526 --- .../importers/max/MaxAseTokenizer.java | 309 -- .../experiments/importers/max/MaxData.java | 96 - .../experiments/importers/max/MaxLoader.java | 363 -- .../experiments/importers/maya/Frame.java | 58 - .../experiments/importers/maya/Joint.java | 101 - .../experiments/importers/maya/Loader.java | 1889 ---------- .../importers/maya/MAttribute.java | 69 - .../importers/maya/MConnection.java | 84 - .../experiments/importers/maya/MEnv.java | 3108 ---------------- .../experiments/importers/maya/MNode.java | 311 -- .../experiments/importers/maya/MNodeType.java | 190 - .../experiments/importers/maya/MObject.java | 58 - .../experiments/importers/maya/MPath.java | 559 --- .../maya/MayaAnimationCurveInterpolator.java | 115 - .../experiments/importers/maya/MayaGroup.java | 106 - .../importers/maya/MayaImporter.java | 170 - .../experiments/importers/maya/Xform.java | 243 -- .../importers/maya/parser/MParser.java | 572 --- .../importers/maya/types/MArrayType.java | 56 - .../maya/types/MAttributeAliasType.java | 55 - .../importers/maya/types/MBoolType.java | 51 - .../maya/types/MCharacterMappingType.java | 55 - .../maya/types/MComponentListType.java | 51 - .../importers/maya/types/MCompoundType.java | 123 - .../importers/maya/types/MDataType.java | 50 - .../maya/types/MFloat2ArrayType.java | 51 - .../importers/maya/types/MFloat2Type.java | 51 - .../maya/types/MFloat3ArrayType.java | 51 - .../importers/maya/types/MFloat3Type.java | 51 - .../importers/maya/types/MFloatArrayType.java | 55 - .../importers/maya/types/MFloatType.java | 51 - .../importers/maya/types/MInt3ArrayType.java | 51 - .../importers/maya/types/MIntArrayType.java | 51 - .../importers/maya/types/MIntType.java | 51 - .../importers/maya/types/MMatrixType.java | 59 - .../importers/maya/types/MNurbsCurveType.java | 51 - .../importers/maya/types/MPointerType.java | 51 - .../importers/maya/types/MPolyFaceType.java | 51 - .../importers/maya/types/MStringType.java | 51 - .../importers/maya/values/MArray.java | 45 - .../maya/values/MAttributeAlias.java | 39 - .../importers/maya/values/MBool.java | 39 - .../maya/values/MCharacterMapping.java | 45 - .../importers/maya/values/MComponentList.java | 132 - .../importers/maya/values/MCompound.java | 48 - .../importers/maya/values/MData.java | 67 - .../importers/maya/values/MFloat.java | 39 - .../importers/maya/values/MFloat2.java | 45 - .../importers/maya/values/MFloat2Array.java | 41 - .../importers/maya/values/MFloat3.java | 47 - .../importers/maya/values/MFloat3Array.java | 41 - .../importers/maya/values/MFloatArray.java | 43 - .../importers/maya/values/MInt.java | 39 - .../importers/maya/values/MInt3Array.java | 41 - .../importers/maya/values/MIntArray.java | 43 - .../importers/maya/values/MNurbsCurve.java | 53 - .../importers/maya/values/MPointer.java | 44 - .../importers/maya/values/MPolyFace.java | 126 - .../importers/maya/values/MString.java | 39 - .../maya/values/impl/MArrayImpl.java | 181 - .../maya/values/impl/MAttributeAliasImpl.java | 82 - .../importers/maya/values/impl/MBoolImpl.java | 74 - .../values/impl/MCharacterMappingImpl.java | 95 - .../maya/values/impl/MComponentListImpl.java | 82 - .../maya/values/impl/MCompoundImpl.java | 107 - .../importers/maya/values/impl/MDataImpl.java | 176 - .../maya/values/impl/MFloat2ArrayImpl.java | 162 - .../maya/values/impl/MFloat2Impl.java | 122 - .../maya/values/impl/MFloat3ArrayImpl.java | 164 - .../maya/values/impl/MFloat3Impl.java | 130 - .../maya/values/impl/MFloatArrayImpl.java | 175 - .../maya/values/impl/MFloatImpl.java | 71 - .../maya/values/impl/MInt3ArrayImpl.java | 151 - .../maya/values/impl/MIntArrayImpl.java | 170 - .../importers/maya/values/impl/MIntImpl.java | 71 - .../maya/values/impl/MNurbsCurveImpl.java | 132 - .../maya/values/impl/MPointerImpl.java | 87 - .../maya/values/impl/MPolyFaceImpl.java | 142 - .../maya/values/impl/MStringImpl.java | 69 - .../importers/obj/FloatArrayList.java | 1284 ------- .../importers/obj/IntegerArrayList.java | 1289 ------- .../experiments/importers/obj/MtlReader.java | 163 - .../importers/obj/ObjImporter.java | 465 --- .../importers/obj/ObjOrPolyObjImporter.java | 76 - .../importers/obj/PolyObjImporter.java | 421 --- .../jfx3dviewer/AutoScalingGroup.java | 158 - .../experiments/jfx3dviewer/ContentModel.java | 884 ----- .../jfx3dviewer/FourWayNavControl.java | 138 - .../javafx/experiments/jfx3dviewer/Frame.java | 75 - .../jfx3dviewer/Jfx3dViewerApp.java | 87 - .../jfx3dviewer/MainController.java | 362 -- .../jfx3dviewer/NavigationController.java | 96 - .../jfx3dviewer/SessionManager.java | 185 - .../jfx3dviewer/SettingsController.java | 516 --- .../jfx3dviewer/SimpleViewerApp.java | 131 - .../jfx3dviewer/SubSceneResizer.java | 93 - .../jfx3dviewer/TimelineController.java | 156 - .../jfx3dviewer/TimelineDisplay.java | 173 - .../experiments/shape3d/PolygonMesh.java | 100 - .../experiments/shape3d/PolygonMeshView.java | 563 --- .../experiments/shape3d/SkinningMesh.java | 249 -- .../experiments/shape3d/SubdivisionMesh.java | 205 -- .../shape3d/symbolic/OriginalPointArray.java | 50 - .../symbolic/SubdividedPointArray.java | 174 - .../shape3d/symbolic/SymbolicPointArray.java | 54 - .../shape3d/symbolic/SymbolicPolygonMesh.java | 74 - .../symbolic/SymbolicSubdivisionBuilder.java | 446 --- .../experiments/utils3d/DragSupport.java | 191 - .../animation/NumberTangentInterpolator.java | 124 - .../utils3d/animation/SplineInterpolator.java | 331 -- .../utils3d/animation/TickCalculation.java | 106 - .../experiments/utils3d/geom/BaseBounds.java | 202 -- .../experiments/utils3d/geom/BoxBounds.java | 615 ---- .../experiments/utils3d/geom/Dimension2D.java | 51 - .../experiments/utils3d/geom/Point2D.java | 252 -- .../experiments/utils3d/geom/RectBounds.java | 639 ---- .../experiments/utils3d/geom/Rectangle.java | 788 ---- .../experiments/utils3d/geom/Vec2f.java | 244 -- .../experiments/utils3d/geom/Vec3d.java | 269 -- .../experiments/utils3d/geom/Vec3f.java | 241 -- .../utils3d/geom/transform/Affine2D.java | 1532 -------- .../utils3d/geom/transform/Affine3D.java | 1168 ------ .../utils3d/geom/transform/AffineBase.java | 3173 ----------------- .../utils3d/geom/transform/BaseTransform.java | 611 ---- .../geom/transform/CanTransformVec3d.java | 41 - .../utils3d/geom/transform/Identity.java | 386 -- .../NoninvertibleTransformException.java | 57 - .../transform/SingularMatrixException.java | 48 - .../geom/transform/TransformHelper.java | 221 -- .../utils3d/geom/transform/Translate2D.java | 627 ---- gui/src/main/java/math/VectorMath.java | 75 - gui/src/main/java/mesh/Ellipse.java | 128 - .../main/java/mesh/polyhedra/Antiprism.java | 81 - .../main/java/mesh/polyhedra/Polyhedron.java | 1272 ------- gui/src/main/java/mesh/polyhedra/Prism.java | 77 - gui/src/main/java/mesh/polyhedra/Pyramid.java | 68 - .../archimedes/ArchimedeanSolid.java | 12 - .../polyhedra/archimedes/Cuboctahedron.java | 29 - .../archimedes/Icosidodecahedron.java | 31 - .../main/java/mesh/polyhedra/plato/Cube.java | 87 - .../mesh/polyhedra/plato/Dodecahedron.java | 151 - .../mesh/polyhedra/plato/Icosahedron.java | 117 - .../java/mesh/polyhedra/plato/Octahedron.java | 97 - .../mesh/polyhedra/plato/PlatonicSolid.java | 37 - .../mesh/polyhedra/plato/Tetrahedron.java | 77 - .../java/mesh/polyhedra/sphere/Goldberg.java | 39 - .../java/mesh/polyhedra/sphere/Icosphere.java | 43 - .../java/mesh/struct/EdgeToAdjacentFace.java | 69 - .../java/mesh/struct/FaceToAdjacentFace.java | 80 - .../struct/OrderedVertexToAdjacentEdge.java | 86 - .../struct/OrderedVertexToAdjacentFace.java | 117 - .../mesh/struct/VertexToAdjacentFace.java | 62 - gui/src/main/java/util/Canonicalize.java | 263 -- gui/src/main/java/util/Geometry.java | 60 - gui/src/main/java/util/PolyhedraUtils.java | 177 - gui/src/main/java/util/Struct.java | 30 - 204 files changed, 1942 insertions(+), 42589 deletions(-) delete mode 100644 core/src/main/java/com/hellblazer/delaunay/Examples.java create mode 100644 core/src/main/java/com/hellblazer/delaunay/sturm/ExpInterval.java create mode 100644 core/src/main/java/com/hellblazer/delaunay/sturm/Interval.java create mode 100644 core/src/main/java/com/hellblazer/delaunay/sturm/Polynomial.java create mode 100644 core/src/main/java/com/hellblazer/delaunay/sturm/SturmRootIsolator.java create mode 100644 core/src/test/java/com/hellblazer/delaunay/Examples.java delete mode 100644 core/src/test/java/com/hellblazer/delaunay/TestVertex.java create mode 100644 core/src/test/java/com/hellblazer/delaunay/sturm/RootIsolatorTest.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/Constants.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/CubicGrid.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/Inspector.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/LinkInspector.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/LinkView.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceInspector.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceView.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/PhiCoordinates.java delete mode 100644 gui/src/main/java/com/hellblazer/delaunay/gui/PointModel.java rename gui/src/main/java/com/hellblazer/{delaunay => voronoi3d}/gui/Colors.java (99%) rename gui/src/main/java/com/hellblazer/{delaunay => voronoi3d}/gui/GraphicsView.java (65%) create mode 100644 gui/src/main/java/com/hellblazer/voronoi3d/gui/TestCases.java create mode 100644 gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationInspector.java rename gui/src/main/java/com/hellblazer/{delaunay => voronoi3d}/gui/TetrahedralizationView.java (68%) rename gui/src/main/java/com/{javafx/experiments/jfx3dviewer => hellblazer/voronoi3d/gui}/Xform.java (77%) rename gui/src/main/java/{ => com/hellblazer/voronoi3d/gui}/mesh/Edge.java (99%) rename gui/src/main/java/{ => com/hellblazer/voronoi3d/gui}/mesh/Face.java (99%) rename gui/src/main/java/{ => com/hellblazer/voronoi3d/gui}/mesh/Line.java (99%) rename gui/src/main/java/{ => com/hellblazer/voronoi3d/gui}/mesh/Mesh.java (99%) rename gui/src/main/java/{ => com/hellblazer/voronoi3d/gui}/mesh/PolyLine.java (97%) delete mode 100644 gui/src/main/java/com/javafx/experiments/exporters/fxml/FXMLExporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/exporters/javasource/JavaSourceExporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalApp.java delete mode 100644 gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalConverter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/Importer.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/Importer3D.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/ImporterFinder.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/Optimizer.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/SmoothingGroups.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/Validator.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/dae/DaeImporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/max/MaxAseParser.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/max/MaxAseTokenizer.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/max/MaxData.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/max/MaxLoader.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/Frame.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/Joint.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/Loader.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MAttribute.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MConnection.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MEnv.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MNode.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MNodeType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MObject.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MPath.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MayaAnimationCurveInterpolator.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MayaGroup.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/MayaImporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/Xform.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/parser/MParser.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MAttributeAliasType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MBoolType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MCharacterMappingType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MComponentListType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MCompoundType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MDataType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2ArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2Type.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3ArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3Type.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MInt3ArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntArrayType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MMatrixType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MNurbsCurveType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MPointerType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MPolyFaceType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/types/MStringType.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MAttributeAlias.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MBool.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MCharacterMapping.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MComponentList.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MCompound.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MData.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2Array.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3Array.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloatArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt3Array.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MIntArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MNurbsCurve.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MPointer.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MPolyFace.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/MString.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MAttributeAliasImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MBoolImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCharacterMappingImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MComponentListImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCompoundImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MDataImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2ArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2Impl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3ArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3Impl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MInt3ArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntArrayImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MNurbsCurveImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPointerImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPolyFaceImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MStringImpl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/FloatArrayList.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/IntegerArrayList.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/MtlReader.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/ObjImporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/ObjOrPolyObjImporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/importers/obj/PolyObjImporter.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/AutoScalingGroup.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/ContentModel.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/FourWayNavControl.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/Frame.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/Jfx3dViewerApp.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/MainController.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/NavigationController.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/SessionManager.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/SettingsController.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/SimpleViewerApp.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/SubSceneResizer.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineController.java delete mode 100644 gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineDisplay.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/PolygonMesh.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/PolygonMeshView.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/SkinningMesh.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/SubdivisionMesh.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/symbolic/OriginalPointArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SubdividedPointArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPointArray.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPolygonMesh.java delete mode 100644 gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicSubdivisionBuilder.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/DragSupport.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/animation/NumberTangentInterpolator.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/animation/SplineInterpolator.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/animation/TickCalculation.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/BaseBounds.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/BoxBounds.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Dimension2D.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Point2D.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/RectBounds.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Rectangle.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec2f.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3d.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3f.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine2D.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine3D.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/AffineBase.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/BaseTransform.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/CanTransformVec3d.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Identity.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/NoninvertibleTransformException.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/SingularMatrixException.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/TransformHelper.java delete mode 100644 gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Translate2D.java delete mode 100644 gui/src/main/java/math/VectorMath.java delete mode 100644 gui/src/main/java/mesh/Ellipse.java delete mode 100644 gui/src/main/java/mesh/polyhedra/Antiprism.java delete mode 100644 gui/src/main/java/mesh/polyhedra/Polyhedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/Prism.java delete mode 100644 gui/src/main/java/mesh/polyhedra/Pyramid.java delete mode 100644 gui/src/main/java/mesh/polyhedra/archimedes/ArchimedeanSolid.java delete mode 100644 gui/src/main/java/mesh/polyhedra/archimedes/Cuboctahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/archimedes/Icosidodecahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/Cube.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/Dodecahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/Icosahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/Octahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/PlatonicSolid.java delete mode 100644 gui/src/main/java/mesh/polyhedra/plato/Tetrahedron.java delete mode 100644 gui/src/main/java/mesh/polyhedra/sphere/Goldberg.java delete mode 100644 gui/src/main/java/mesh/polyhedra/sphere/Icosphere.java delete mode 100644 gui/src/main/java/mesh/struct/EdgeToAdjacentFace.java delete mode 100644 gui/src/main/java/mesh/struct/FaceToAdjacentFace.java delete mode 100644 gui/src/main/java/mesh/struct/OrderedVertexToAdjacentEdge.java delete mode 100644 gui/src/main/java/mesh/struct/OrderedVertexToAdjacentFace.java delete mode 100644 gui/src/main/java/mesh/struct/VertexToAdjacentFace.java delete mode 100644 gui/src/main/java/util/Canonicalize.java delete mode 100644 gui/src/main/java/util/Geometry.java delete mode 100644 gui/src/main/java/util/PolyhedraUtils.java delete mode 100644 gui/src/main/java/util/Struct.java diff --git a/README.md b/README.md index 5ed9f35..2a228fb 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,15 @@ This library is licensed under the AGPL v3.0, requires Java 20+ and is built wit mvn clean install ## Current Status -Raised from the dead. The GUI is now a crude, but servicable Java/FX GUI. Probably will work on cleaning that up and improving that, but... +Raised from the dead. The GUI is now a very crude, but servicable Java/FX GUI. Probably will work on cleaning that up and improving that, but... + +The current implementation leaves flat tetrahedra when processing the cubic example test cases. :: big sad :: My understanding is that these can be removed with 4 <-> 4 flips, so enjoy! ## Maven Artifacts -Currently, Voronoi-3D is in active development and does not publish to maven central. Rather, periodic snapshots (and releases when they happen) -will be uploaded to the [repo-hell]() repository. If you would like to use Voronoi-3D maven artifacts, you'll need to add the following repository -declarations to your pom.xml The maven coordinates for individual artifacts are found below. +Currently, Voronoi-3D is snapshot development and does not publish to maven central. Rather, periodic snapshots (and releases when they happen) +will be uploaded to the [repo-hell](https://raw.githubusercontent.com/Hellblazer/repo-hell/main/mvn-artifact) repository. If you would like to +use Voronoi-3D maven artifacts, you'll need to add the following repository declarations to your pom.xml The maven coordinates for individual +artifacts are found below. diff --git a/core/src/main/java/com/hellblazer/delaunay/Examples.java b/core/src/main/java/com/hellblazer/delaunay/Examples.java deleted file mode 100644 index 922b48e..0000000 --- a/core/src/main/java/com/hellblazer/delaunay/Examples.java +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Copyright (C) 2008 Hal Hildebrand. All rights reserved. - * - * This file is part of the 3D Incremental Voronoi GUI - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.hellblazer.delaunay; - -import java.util.ArrayList; - -/** - * - * @author Hal Hildebrand - * - */ - -public class Examples { - - public static Vertex[] getCubicCrystalStructure() { - ArrayList list = new ArrayList<>(); - list.add(new Vertex(-0.89999799999999996D, -0.89999200000000001D, -0.900003D)); - list.add(new Vertex(-0.90000199999999997D, -0.90000800000000003D, -6.9999999999999999E-06D)); - list.add(new Vertex(-0.89999499999999999D, -0.90000199999999997D, 0.900003D)); - list.add(new Vertex(-0.89999099999999999D, 5.0000000000000004E-06D, -0.89999099999999999D)); - list.add(new Vertex(-0.89999399999999996D, 9.9999999999999995E-07D, 5.0000000000000004E-06D)); - list.add(new Vertex(-0.90000800000000003D, 5.0000000000000004E-06D, 0.90000500000000005D)); - list.add(new Vertex(-0.89999499999999999D, 0.89999099999999999D, -0.89999600000000002D)); - list.add(new Vertex(-0.90000100000000005D, 0.90000000000000002D, -1.9999999999999999E-06D)); - list.add(new Vertex(-0.89999499999999999D, 0.90000199999999997D, 0.89999899999999999D)); - list.add(new Vertex(-6.0000000000000002E-06D, -0.89999600000000002D, -0.90000599999999997D)); - list.add(new Vertex(-6.0000000000000002E-06D, -0.900007D, -6.0000000000000002E-06D)); - list.add(new Vertex(-3.0000000000000001E-06D, -0.90000100000000005D, 0.89999600000000002D)); - list.add(new Vertex(3.9999999999999998E-06D, 0.0D, -0.89999399999999996D)); - list.add(new Vertex(-9.0000000000000002E-06D, 5.0000000000000004E-06D, 1.0000000000000001E-05D)); - list.add(new Vertex(-6.0000000000000002E-06D, -1.9999999999999999E-06D, 0.89999799999999996D)); - list.add(new Vertex(9.0000000000000002E-06D, 0.89999600000000002D, -0.90000599999999997D)); - list.add(new Vertex(1.0000000000000001E-05D, 0.90000100000000005D, 3.9999999999999998E-06D)); - list.add(new Vertex(-6.9999999999999999E-06D, 0.90000899999999995D, 0.89999600000000002D)); - list.add(new Vertex(0.89999799999999996D, -0.90000800000000003D, -0.89999600000000002D)); - list.add(new Vertex(0.90000500000000005D, -0.89999899999999999D, -1.9999999999999999E-06D)); - list.add(new Vertex(0.89999600000000002D, -0.89999099999999999D, 0.90000199999999997D)); - list.add(new Vertex(0.89999499999999999D, 9.9999999999999995E-07D, -0.89999700000000005D)); - list.add(new Vertex(0.90000500000000005D, -5.0000000000000004E-06D, -3.9999999999999998E-06D)); - list.add(new Vertex(0.89999799999999996D, -3.9999999999999998E-06D, 0.89999899999999999D)); - list.add(new Vertex(0.90000599999999997D, 0.900003D, -0.89999600000000002D)); - list.add(new Vertex(0.89999600000000002D, 0.89999899999999999D, -6.9999999999999999E-06D)); - list.add(new Vertex(0.90000400000000003D, 0.89999499999999999D, 0.900003D)); - list.add(new Vertex(-0.44999499999999998D, -0.44999099999999997D, -0.45001000000000002D)); - list.add(new Vertex(-0.45000200000000001D, -0.45000499999999999D, 0.44999499999999998D)); - list.add(new Vertex(-0.449992D, 0.44999099999999997D, -0.449992D)); - list.add(new Vertex(-0.44999499999999998D, 0.45000600000000002D, 0.44999099999999997D)); - list.add(new Vertex(0.45000099999999998D, -0.44999600000000001D, -0.44999600000000001D)); - list.add(new Vertex(0.44999800000000001D, -0.45000899999999999D, 0.44999299999999998D)); - list.add(new Vertex(0.44999400000000001D, 0.44999499999999998D, -0.45000800000000002D)); - list.add(new Vertex(0.45000800000000002D, 0.44999600000000001D, 0.45000699999999999D)); - return list.toArray(new Vertex[list.size()]); - } - - public static Vertex[] getGrid() { - ArrayList list; - list = new ArrayList<>(); - list.add(new Vertex(-0.74999800000000005D, -0.74999199999999999D, -0.75000299999999998D)); - list.add(new Vertex(-0.75000199999999995D, -0.75000800000000001D, -0.25000699999999998D)); - list.add(new Vertex(-0.74999499999999997D, -0.75000199999999995D, 0.25000299999999998D)); - list.add(new Vertex(-0.74999099999999996D, -0.74999499999999997D, 0.75000900000000004D)); - list.add(new Vertex(-0.74999400000000005D, -0.249999D, -0.74999499999999997D)); - list.add(new Vertex(-0.75000800000000001D, -0.24999499999999999D, -0.24999499999999999D)); - list.add(new Vertex(-0.74999499999999997D, -0.25000899999999998D, 0.250004D)); - list.add(new Vertex(-0.75000100000000003D, -0.25D, 0.74999800000000005D)); - list.add(new Vertex(-0.74999499999999997D, 0.250002D, -0.75000100000000003D)); - list.add(new Vertex(-0.75000599999999995D, 0.250004D, -0.25000600000000001D)); - list.add(new Vertex(-0.75000599999999995D, 0.24999299999999999D, 0.24999399999999999D)); - list.add(new Vertex(-0.75000299999999998D, 0.249999D, 0.749996D)); - list.add(new Vertex(-0.749996D, 0.75D, -0.74999400000000005D)); - list.add(new Vertex(-0.75000900000000004D, 0.75000500000000003D, -0.24998999999999999D)); - list.add(new Vertex(-0.75000599999999995D, 0.74999800000000005D, 0.249998D)); - list.add(new Vertex(-0.74999099999999996D, 0.749996D, 0.74999400000000005D)); - list.add(new Vertex(-0.24998999999999999D, -0.74999899999999997D, -0.749996D)); - list.add(new Vertex(-0.25000699999999998D, -0.74999099999999996D, -0.250004D)); - list.add(new Vertex(-0.250002D, -0.75000800000000001D, 0.250004D)); - list.add(new Vertex(-0.24999499999999999D, -0.74999899999999997D, 0.74999800000000005D)); - list.add(new Vertex(-0.250004D, -0.24999099999999999D, -0.74999800000000005D)); - list.add(new Vertex(-0.25000499999999998D, -0.249999D, -0.249997D)); - list.add(new Vertex(-0.24999499999999999D, -0.25000499999999998D, 0.249996D)); - list.add(new Vertex(-0.250002D, -0.250004D, 0.74999899999999997D)); - list.add(new Vertex(-0.24999399999999999D, 0.25000299999999998D, -0.749996D)); - list.add(new Vertex(-0.250004D, 0.249999D, -0.25000699999999998D)); - list.add(new Vertex(-0.249996D, 0.24999499999999999D, 0.25000299999999998D)); - list.add(new Vertex(-0.24999499999999999D, 0.25000899999999998D, 0.74999000000000005D)); - list.add(new Vertex(-0.250002D, 0.74999499999999997D, -0.75000500000000003D)); - list.add(new Vertex(-0.24999199999999999D, 0.74999099999999996D, -0.24999199999999999D)); - list.add(new Vertex(-0.24999499999999999D, 0.75000599999999995D, 0.24999099999999999D)); - list.add(new Vertex(-0.249999D, 0.750004D, 0.750004D)); - list.add(new Vertex(0.249998D, -0.75000900000000004D, -0.75000699999999998D)); - list.add(new Vertex(0.24999399999999999D, -0.75000500000000003D, -0.25000800000000001D)); - list.add(new Vertex(0.25000800000000001D, -0.750004D, 0.25000699999999998D)); - list.add(new Vertex(0.25000099999999997D, -0.75D, 0.75000800000000001D)); - list.add(new Vertex(0.250002D, -0.25000699999999998D, -0.75000900000000004D)); - list.add(new Vertex(0.249997D, -0.249997D, -0.24999299999999999D)); - list.add(new Vertex(0.249996D, -0.24999499999999999D, 0.25001000000000001D)); - list.add(new Vertex(0.25000800000000001D, -0.25000699999999998D, 0.75000100000000003D)); - list.add(new Vertex(0.24999499999999999D, 0.249996D, -0.749996D)); - list.add(new Vertex(0.249998D, 0.250004D, -0.24999099999999999D)); - list.add(new Vertex(0.249998D, 0.25000099999999997D, 0.25000299999999998D)); - list.add(new Vertex(0.25000099999999997D, 0.24999399999999999D, 0.74999300000000002D)); - list.add(new Vertex(0.25001000000000001D, 0.749996D, -0.75000699999999998D)); - list.add(new Vertex(0.250004D, 0.750004D, -0.25000899999999998D)); - list.add(new Vertex(0.25000800000000001D, 0.74999099999999996D, 0.249996D)); - list.add(new Vertex(0.24999299999999999D, 0.74999000000000005D, 0.75000100000000003D)); - list.add(new Vertex(0.75000299999999998D, -0.74999700000000002D, -0.75000900000000004D)); - list.add(new Vertex(0.74999899999999997D, -0.75000199999999995D, -0.24999399999999999D)); - list.add(new Vertex(0.74999700000000002D, -0.75000599999999995D, 0.249997D)); - list.add(new Vertex(0.75000900000000004D, -0.75000800000000001D, 0.75D)); - list.add(new Vertex(0.75000900000000004D, -0.24999499999999999D, -0.74999499999999997D)); - list.add(new Vertex(0.74999800000000005D, -0.25000899999999998D, -0.250002D)); - list.add(new Vertex(0.75D, -0.250004D, 0.25000699999999998D)); - list.add(new Vertex(0.749996D, -0.25D, 0.749996D)); - list.add(new Vertex(0.75000199999999995D, 0.24999199999999999D, -0.75000500000000003D)); - list.add(new Vertex(0.750004D, 0.25000899999999998D, -0.25D)); - list.add(new Vertex(0.75000500000000003D, 0.25001000000000001D, 0.250002D)); - list.add(new Vertex(0.74999800000000005D, 0.25000699999999998D, 0.75000599999999995D)); - list.add(new Vertex(0.75000599999999995D, 0.75000299999999998D, -0.75D)); - list.add(new Vertex(0.74999199999999999D, 0.74999800000000005D, -0.25000600000000001D)); - list.add(new Vertex(0.74999300000000002D, 0.74999400000000005D, 0.24998999999999999D)); - list.add(new Vertex(0.75000299999999998D, 0.75000699999999998D, 0.75000199999999995D)); - return list.toArray(new Vertex[list.size()]); - } - - public static Vertex[] getWorstCase() { - ArrayList list; - list = new ArrayList<>(); - - list.add(new Vertex(-0.36000100000000002D, 7.9999999999999996E-06D, 0.96000099999999999D)); - list.add(new Vertex(0.120003D, 0.88000900000000004D, 0.120002D)); - list.add(new Vertex(-0.30000100000000002D, 0.0D, 0.900003D)); - list.add(new Vertex(0.100004D, 0.80000899999999997D, 0.100007D)); - list.add(new Vertex(-0.240008D, 7.9999999999999996E-06D, 0.84000399999999997D)); - list.add(new Vertex(0.080005999999999994D, 0.72000699999999995D, 0.080005000000000007D)); - list.add(new Vertex(-0.180009D, 6.0000000000000002E-06D, 0.780003D)); - list.add(new Vertex(0.060006999999999998D, 0.64000500000000005D, 0.060002D)); - list.add(new Vertex(-0.120005D, 3.9999999999999998E-06D, 0.72000900000000001D)); - list.add(new Vertex(0.040003999999999998D, 0.56000300000000003D, 0.040004999999999999D)); - list.add(new Vertex(-0.060003000000000001D, 1.9999999999999999E-06D, 0.66000300000000001D)); - list.add(new Vertex(0.020004000000000001D, 0.48000100000000001D, 0.020001999999999999D)); - list.add(new Vertex(6.0000000000000002E-06D, 9.0000000000000002E-06D, 0.60000600000000004D)); - list.add(new Vertex(6.0000000000000002E-06D, 0.40000799999999997D, 9.0000000000000002E-06D)); - list.add(new Vertex(0.060000999999999999D, 6.9999999999999999E-06D, 0.54000800000000004D)); - list.add(new Vertex(-0.020003D, 0.32000600000000001D, -0.020005999999999999D)); - list.add(new Vertex(0.120007D, 5.0000000000000004E-06D, 0.48000399999999999D)); - list.add(new Vertex(-0.040003999999999998D, 0.240004D, -0.040003999999999998D)); - list.add(new Vertex(0.180008D, 3.0000000000000001E-06D, 0.42000300000000002D)); - list.add(new Vertex(-0.060000999999999999D, 0.16000200000000001D, -0.060002D)); - list.add(new Vertex(0.240007D, 9.9999999999999995E-07D, 0.36000700000000002D)); - list.add(new Vertex(-0.080004000000000006D, 0.080004000000000006D, -0.080008999999999997D)); - list.add(new Vertex(0.30000199999999999D, 1.9999999999999999E-06D, 0.30000100000000002D)); - list.add(new Vertex(-0.10000299999999999D, 3.0000000000000001E-06D, -0.10000199999999999D)); - list.add(new Vertex(0.36000399999999999D, 6.0000000000000002E-06D, 0.240006D)); - list.add(new Vertex(-0.120005D, -0.080004000000000006D, -0.120003D)); - list.add(new Vertex(0.42000599999999999D, 6.9999999999999999E-06D, 0.180009D)); - list.add(new Vertex(-0.14000699999999999D, -0.160001D, -0.14000199999999999D)); - list.add(new Vertex(0.48000799999999999D, 3.0000000000000001E-06D, 0.120003D)); - list.add(new Vertex(-0.16000900000000001D, -0.240006D, -0.16000600000000001D)); - list.add(new Vertex(0.54000099999999995D, 1.9999999999999999E-06D, 0.060000600000000001D)); - list.add(new Vertex(-0.180002D, -0.32000299999999998D, -0.18000099999999999D)); - list.add(new Vertex(0.60000299999999995D, 3.9999999999999998E-06D, 5.0000000000000004E-06D)); - list.add(new Vertex(-0.20000399999999999D, -0.40000599999999997D, -0.20000200000000001D)); - list.add(new Vertex(0.66000499999999995D, 6.9999999999999999E-06D, -0.060003000000000001D)); - list.add(new Vertex(-0.22000600000000001D, -0.48000900000000002D, -0.22000600000000001D)); - list.add(new Vertex(0.72000699999999995D, 7.9999999999999996E-06D, -0.120004D)); - list.add(new Vertex(-0.240008D, -0.56000399999999995D, -0.24000299999999999D)); - list.add(new Vertex(0.78000899999999995D, 5.0000000000000004E-06D, -0.180007D)); - list.add(new Vertex(-0.26000200000000001D, -0.64000699999999999D, -0.26000400000000001D)); - list.add(new Vertex(0.840001D, 7.9999999999999996E-06D, -0.24000199999999999D)); - list.add(new Vertex(-0.280003D, -0.720001D, -0.280005D)); - list.add(new Vertex(0.90000500000000005D, 3.0000000000000001E-06D, -0.30000700000000002D)); - list.add(new Vertex(-0.30000300000000002D, -0.80000499999999997D, -0.30000300000000002D)); - list.add(new Vertex(0.96000099999999999D, 1.9999999999999999E-06D, -0.36000700000000002D)); - list.add(new Vertex(-0.32000899999999999D, -0.88000100000000003D, -0.32000299999999998D)); - return list.toArray(new Vertex[list.size()]); - } -} diff --git a/core/src/main/java/com/hellblazer/delaunay/Geometry.java b/core/src/main/java/com/hellblazer/delaunay/Geometry.java index 37b93d9..17452c4 100644 --- a/core/src/main/java/com/hellblazer/delaunay/Geometry.java +++ b/core/src/main/java/com/hellblazer/delaunay/Geometry.java @@ -6,6 +6,9 @@ ****************************************************************************/ package com.hellblazer.delaunay; +import javax.vecmath.Point3d; +import javax.vecmath.Tuple3d; + /** * Robust geometric predicates. *

@@ -57,27 +60,6 @@ private static class Two { private static final double SPLITTER; - static { - double epsilon = 1.0; - double splitter = 1.0; - boolean everyOther = true; - do { - epsilon *= 0.5; - if (everyOther) { - splitter *= 2.0; - } - everyOther = !everyOther; - } while (1.0 + epsilon != 1.0); - splitter += 1.0; - EPSILON = epsilon; - SPLITTER = splitter; - O2DERRBOUND = 4.0 * EPSILON; - O3DERRBOUND = 8.0 * EPSILON; - INCERRBOUND = 11.0 * EPSILON; - INSERRBOUND = 17.0 * EPSILON; - IOSERRBOUND = 19.0 * EPSILON; - } - /** * Computes the center of the circle defined by the points a, b, and c. The * latter are assumed to be in CCW order, such that the method @@ -245,6 +227,57 @@ public static void centerSphere(float[] pa, float[] pb, float[] pc, float[] pd, centerSphere(pa[0], pa[1], pa[2], pb[0], pb[1], pb[2], pc[0], pc[1], pc[2], pd[0], pd[1], pd[2], po); } + public static Point3d[] findLineSphereIntersections(Tuple3d linePoint0, Tuple3d linePoint1, Tuple3d circleCenter, + double circleRadius) { + // http://www.codeproject.com/Articles/19799/Simple-Ray-Tracing-in-C-Part-II-Triangles-Intersec + + double cx = circleCenter.x; + double cy = circleCenter.y; + double cz = circleCenter.z; + + double px = linePoint0.x; + double py = linePoint0.y; + double pz = linePoint0.z; + + double vx = linePoint1.x - px; + double vy = linePoint1.y - py; + double vz = linePoint1.z - pz; + + double A = vx * vx + vy * vy + vz * vz; + double B = 2.0 * (px * vx + py * vy + pz * vz - vx * cx - vy * cy - vz * cz); + double C = px * px - 2 * px * cx + cx * cx + py * py - 2 * py * cy + cy * cy + pz * pz - 2 * pz * cz + cz * cz + - circleRadius * circleRadius; + + // discriminant + double D = B * B - 4 * A * C; + + if (D < 0) { + return new Point3d[0]; + } + + double t1 = (-B - Math.sqrt(D)) / (2.0 * A); + + Point3d solution1 = new Point3d(linePoint0.x * (1 - t1) + t1 * linePoint1.x, + linePoint0.y * (1 - t1) + t1 * linePoint1.y, + linePoint0.z * (1 - t1) + t1 * linePoint1.z); + if (D == 0) { + return new Point3d[] { solution1 }; + } + + double t2 = (-B + Math.sqrt(D)) / (2.0 * A); + Point3d solution2 = new Point3d(linePoint0.x * (1 - t2) + t2 * linePoint1.x, + linePoint0.y * (1 - t2) + t2 * linePoint1.y, + linePoint0.z * (1 - t2) + t2 * linePoint1.z); + + // prefer a solution that's on the line segment itself + + if (Math.abs(t1 - 0.5) < Math.abs(t2 - 0.5)) { + return new Point3d[] { solution1, solution2 }; + } + + return new Point3d[] { solution2, solution1 }; + } + /** * Determines if a point d is inside the circle defined by the points a, b, and * c. The latter are assumed to be in CCW order, such that the method @@ -898,19 +931,6 @@ public static double leftOfLine(float[] pa, float[] pb, float[] pc) { return leftOfLine(pa[0], pa[1], pb[0], pb[1], pc[0], pc[1]); } - /////////////////////////////////////////////////////////////////////////// - // private - - /////////////////////////////////////////////////////////////////////////// - // Java implementation of Jonathan Shewchuk's functions for arbitrary - // floating-point arithmetic and fast robust geometric predicates. - // Only Shewchuk's "slow" exact methods are implemented here. - // If the methods above lack sufficient precision, then they call - // the slow methods below. This is equivalent to using only stages A - // and D of Shewchuk's adaptive methods with stages A, B, C, and D. - // Note that the error bounds used here to determine whether an fast - // method is accurate are simpler and more conservative than Shewchuk's. - /** * Determines if a point c is left of the line defined by the points a and b. * This is equivalent to determining whether the points a, b, and c are in @@ -929,6 +949,19 @@ public static double leftOfLineFast(double xa, double ya, double xb, double yb, return acx * bcy - acy * bcx; } + /////////////////////////////////////////////////////////////////////////// + // private + + /////////////////////////////////////////////////////////////////////////// + // Java implementation of Jonathan Shewchuk's functions for arbitrary + // floating-point arithmetic and fast robust geometric predicates. + // Only Shewchuk's "slow" exact methods are implemented here. + // If the methods above lack sufficient precision, then they call + // the slow methods below. This is equivalent to using only stages A + // and D of Shewchuk's adaptive methods with stages A, B, C, and D. + // Note that the error bounds used here to determine whether an fast + // method is accurate are simpler and more conservative than Shewchuk's. + /** * Determines if a point c is left of the line defined by the points a and b. * This is equivalent to determining whether the points a, b, and c are in @@ -1717,15 +1750,6 @@ private static double inOrthoSphereExact(double xa, double ya, double za, double return det[detlen - 1]; } - /** - * Computes difference a-b, assuming that |a|>=|b|. Puts result in x and - * error in y. - */ - /* - * private strictfp static void twoDiffFast(double a, double b, Two t) { double - * x = a-b; double bvirt = a-x; t.x = x; t.y = bvirt-b; } - */ - /** * Slow exact 3D in-sphere test. Returns a positive value if the point pe lies * inside the sphere passing through pa, pb, pc, and pd; a negative value if it @@ -2053,14 +2077,12 @@ private static double inSphereExact(double xa, double ya, double za, double xb, } /** - * Computes the product a*b. Puts the product in x and the error in y. + * Computes difference a-b, assuming that |a|>=|b|. Puts result in x and + * error in y. */ /* - * private strictfp static void twoProduct(double a, double b, Two t) { double x - * = a*b; split(a,t); double ahi = t.x; double alo = t.y; split(b,t); double bhi - * = t.x; double blo = t.y; double err1 = x-(ahi*bhi); double err2 = - * err1-(alo*bhi); double err3 = err2-(ahi*blo); t.x = x; t.y = (alo*blo)-err3; - * } + * private strictfp static void twoDiffFast(double a, double b, Two t) { double + * x = a-b; double bvirt = a-x; t.x = x; t.y = bvirt-b; } */ /** @@ -2098,6 +2120,17 @@ private static double leftOfLineExact(double xa, double ya, double xb, double yb return det[detlen - 1]; } + /** + * Computes the product a*b. Puts the product in x and the error in y. + */ + /* + * private strictfp static void twoProduct(double a, double b, Two t) { double x + * = a*b; split(a,t); double ahi = t.x; double alo = t.y; split(b,t); double bhi + * = t.x; double blo = t.y; double err1 = x-(ahi*bhi); double err2 = + * err1-(alo*bhi); double err3 = err2-(ahi*blo); t.x = x; t.y = (alo*blo)-err3; + * } + */ + /** * Slow exact 3D orientation test. Returns a positive value if the point d lies * left of the plane passing through pa, pb, and pc; here, "left" is defined so @@ -2386,4 +2419,25 @@ private static void twoTwoProduct(double a1, double a0, double b1, double b0, do x[7] = t.x; x[6] = t.y; } + + static { + double epsilon = 1.0; + double splitter = 1.0; + boolean everyOther = true; + do { + epsilon *= 0.5; + if (everyOther) { + splitter *= 2.0; + } + everyOther = !everyOther; + } while (1.0 + epsilon != 1.0); + splitter += 1.0; + EPSILON = epsilon; + SPLITTER = splitter; + O2DERRBOUND = 4.0 * EPSILON; + O3DERRBOUND = 8.0 * EPSILON; + INCERRBOUND = 11.0 * EPSILON; + INSERRBOUND = 17.0 * EPSILON; + IOSERRBOUND = 19.0 * EPSILON; + } } diff --git a/core/src/main/java/com/hellblazer/delaunay/Tetrahedralization.java b/core/src/main/java/com/hellblazer/delaunay/Tetrahedralization.java index a7043ce..5065f26 100644 --- a/core/src/main/java/com/hellblazer/delaunay/Tetrahedralization.java +++ b/core/src/main/java/com/hellblazer/delaunay/Tetrahedralization.java @@ -24,9 +24,7 @@ import static com.hellblazer.delaunay.V.C; import static com.hellblazer.delaunay.V.D; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; import java.util.Deque; import java.util.LinkedList; import java.util.List; @@ -34,7 +32,8 @@ import java.util.Set; import java.util.Stack; -import javax.vecmath.Point3f; +import javax.vecmath.Point3d; +import javax.vecmath.Tuple3d; /** * A Delaunay tetrahedralization. @@ -130,8 +129,18 @@ public Tetrahedralization(Random random) { public void delete(Vertex v) { assert v != null; - LinkedList ears = getEars(v); - while (v.getOrder() > 4) { + LinkedList ears = v.getEars(); + class OC implements StarVisitor { + int order = 0; + + @Override + public void visit(V vertex, Tetrahedron t, Vertex x, Vertex y, Vertex z) { + order++; + } + } + var oc = new OC(); + v.getAdjacent().visitStar(v, oc); + while (oc.order > 4) { for (int i = 0; i < ears.size();) { if (ears.get(i).flip(i, ears, v)) { ears.remove(i); @@ -144,41 +153,6 @@ public void delete(Vertex v) { size--; } - public LinkedList getEars(Vertex v) { - assert v != null && v.getAdjacent() != null; - EarSet aggregator = new EarSet(); - v.getAdjacent().visitStar(v, aggregator); - return aggregator.getEars(); - } - - /** - * Answer the collection of neighboring vertices around the indicated vertex. - * - * @param v - the vertex determining the neighborhood - * @return the collection of neighboring vertices - */ - public Collection getNeighbors(Vertex v) { - assert v != null && v.getAdjacent() != null; - - final Set neighbors = new IdentitySet<>(); - v.getAdjacent().visitStar(v, (V vertex, Tetrahedron t, Vertex x, Vertex y, Vertex z) -> { - neighbors.add(x); - neighbors.add(y); - neighbors.add(z); - }); - return neighbors; - } - - public Deque getStar(Vertex v) { - assert v != null && v.getAdjacent() != null; - - final Deque star = new ArrayDeque<>(); - v.getAdjacent().visitStar(v, (V vertex, Tetrahedron t, Vertex x, Vertex y, Vertex z) -> { - star.push(t.getFace(vertex)); - }); - return star; - } - /** * Answer the set of all tetrahedrons in this tetrahedralization * @@ -233,42 +207,42 @@ public Set getVertices() { } /** - * Answer the faces of the voronoi region around the vertex + * Insert the point into the tetrahedralization. See "Computing the 3D Voronoi + * Diagram Robustly: An Easy Explanation", by Hugo Ledoux + *

* - * @param v - the vertex of interest - * @return the list of faces defining the voronoi region defined by v + * @param p - the point to be inserted + * @return the Vertex in the tetrahedralization */ - public List getVoronoiRegion(final Vertex v) { - assert v != null && v.getAdjacent() != null; - - final ArrayList faces = new ArrayList<>(); - Set neighbors = new IdentitySet<>(10); - v.getAdjacent().visitStar(v, (V vertex, Tetrahedron t, Vertex x, Vertex y, Vertex z) -> { - if (neighbors.add(x)) { - t.traverseVoronoiFace(v, x, faces); - } - if (neighbors.add(y)) { - t.traverseVoronoiFace(v, y, faces); - } - if (neighbors.add(z)) { - t.traverseVoronoiFace(v, z, faces); + public Vertex insert(Point3d p) { + assert p != null; + List ears = new ArrayList<>(); + var v = new Vertex(p); + last = locate(p, last).flip1to4(v, ears); + while (!ears.isEmpty()) { + Tetrahedron l = ears.remove(ears.size() - 1).flip(v, ears); + if (l != null) { + last = l; } - }); - return faces; + } + size++; + return v; } /** - * Insert the vertex into the tetrahedralization. See "Computing the 3D Voronoi + * Insert the point into the tetrahedralization. See "Computing the 3D Voronoi * Diagram Robustly: An Easy Explanation", by Hugo Ledoux *

* - * @param v - the vertex to be inserted + * @param p - the point to be inserted + * @param near - the nearby vertex + * @return the new Vertex in the tetrahedralization */ - public void insert(Vertex v) { - assert v != null; - v.reset(); + public Vertex insert(Point3d p, Vertex near) { + assert p != null; List ears = new ArrayList<>(); - last = locate(v).flip1to4(v, ears); + var v = new Vertex(p); + last = locate(p, near.getAdjacent()).flip1to4(v, ears); while (!ears.isEmpty()) { Tetrahedron l = ears.remove(ears.size() - 1).flip(v, ears); if (l != null) { @@ -276,6 +250,7 @@ public void insert(Vertex v) { } } size++; + return v; } /** @@ -284,35 +259,40 @@ public void insert(Vertex v) { * variation of the 3D jump and walk algorithm found in: "Fast randomized point * location without preprocessing in two- and three-dimensional Delaunay * triangulations", Computational Geometry 12 (1999) 63-83. - *

- * In this variant, the intial "random" triangle used is simply the one of the - * triangles in the last tetrahedron created by a flip, or the previously - * located tetrahedron. - *

- * This location algorithm provides fast location results with no memory - * overhead. Further, because there is no search structure to maintain, this - * algorithm is ideally suited for incremental deletions and kinetic maintenance - * of the delaunay tetrahedralization. - *

* * @param query - the query point - * @return + * @return the Tetrahedron containing the query + */ + public Tetrahedron locate(Tuple3d query) { + return locate(query, last); + } + + /** + * Locate the tetrahedron which contains the query point via a stochastic walk + * through the delaunay triangulation. This location algorithm is a slight + * variation of the 3D jump and walk algorithm found in: "Fast randomized point + * location without preprocessing in two- and three-dimensional Delaunay + * triangulations", Computational Geometry 12 (1999) 63-83. + * + * @param query - the query point + * @param start - the starting tetrahedron + * @return the Tetrahedron containing the query */ - public Tetrahedron locate(Vertex query) { + public Tetrahedron locate(Tuple3d query, Tetrahedron start) { assert query != null; V o = null; for (V face : Tetrahedralization.VERTICES) { - if (last.orientationWrt(face, query) < 0) { + if (start.orientationWrt(face, query) < 0) { o = face; break; } } if (o == null) { // The query point is contained in the receiver - return last; + return start; } - Tetrahedron current = last; + Tetrahedron current = start; while (true) { // get the tetrahedron on the other side of the face Tetrahedron tetrahedron = current.getNeighbor(o); @@ -325,8 +305,7 @@ public Tetrahedron locate(Vertex query) { break; } if (i++ == 2) { - last = tetrahedron; - return last; + return tetrahedron; } } } @@ -346,6 +325,14 @@ public Tetrahedron myOwnPrivateIdaho() { return new Tetrahedron(U); } + /** + * @return - a "random" Tetrahedron from the receiver. This implementation + * returns the last Tetrahedron of the receiver + */ + public Tetrahedron randomPick() { + return last; + } + /** * Traverse all the tetrahedrons in the tetrahedralization. The set of * tetrahedons will be filled with all the tetrahedrons and the set of vertices @@ -381,7 +368,7 @@ public void traverse(Set tetrahedrons, Set vertices) { * @return the tetrahedron created from the flip */ protected Tetrahedron flip4to1(Vertex n) { - Deque star = getStar(n); + Deque star = n.getStar(); ArrayList deleted = new ArrayList<>(); for (OrientedFace f : star) { deleted.add(f.getIncident()); diff --git a/core/src/main/java/com/hellblazer/delaunay/Tetrahedron.java b/core/src/main/java/com/hellblazer/delaunay/Tetrahedron.java index 77c9835..2944d9d 100644 --- a/core/src/main/java/com/hellblazer/delaunay/Tetrahedron.java +++ b/core/src/main/java/com/hellblazer/delaunay/Tetrahedron.java @@ -31,7 +31,8 @@ import java.util.Set; import java.util.Stack; -import javax.vecmath.Point3f; +import javax.vecmath.Point3d; +import javax.vecmath.Tuple3d; /** * An oriented, delaunay tetrahedral cell. The vertices of the tetrahedron are @@ -559,6 +560,53 @@ public String toString() { private static final V[][] VORONOI_FACE_ORIGIN = { { null, C, D, B }, { C, null, D, A }, { D, A, null, B }, { B, C, A, null } }; + /** + * Return +1 if the qeury lies inside the sphere passing through a, b, c, and d; + * -1 if it lies outside; and 0 if the five points are cospherical. The vertices + * a, b, c, and d must be ordered so that they have a positive orientation (as + * defined by {@link #orientation(Vertex, Vertex, Vertex)}), or the sign of the + * result will be reversed. + *

+ * + * @param query - the point to query + * @param a , b, c, d - the points defining the sphere, in oriented order + * @return +1 if the query lies inside the sphere passing through a, b, c, and + * d; -1 if it lies outside; and 0 if the five points are cospherical + */ + + public static final int inSphere(Tuple3d query, Tuple3d a, Tuple3d b, Tuple3d c, Tuple3d d) { + double result = Geometry.inSphere(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, d.x, d.y, d.z, query.x, query.y, + query.z); + if (result > 0.0) { + return 1; + } else if (result < 0.0) { + return -1; + } + return 0; + + } + + /** + * Answer +1 if the orientation of the query is positive with respect to the + * plane defined by {a, b, c}, -1 if negative, or 0 if the test point is + * coplanar + *

+ * + * @param query - the point to query + * @param a , b, c - the points defining the plane + * @return +1 if the orientation of the query point is positive with respect to + * the plane, -1 if negative and 0 if the test point is coplanar + */ + public static int orientation(Tuple3d query, Tuple3d a, Tuple3d b, Tuple3d c) { + double result = Geometry.leftOfPlane(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, query.x, query.y, query.z); + if (result > 0.0) { + return 1; + } else if (result < 0.0) { + return -1; + } + return 0; + } + /** * Vertex A */ @@ -643,18 +691,6 @@ public void addFaces(List faces) { faces.add(new Vertex[] { d, a, c }); } - /** - * Add the four faces defined by the tetrahedron to the list of faces - * - * @param faces - */ - public void addFacesCoordinates(List faces) { - faces.add(new Point3f[] { a.asPoint3f(), d.asPoint3f(), b.asPoint3f() }); - faces.add(new Point3f[] { b.asPoint3f(), c.asPoint3f(), a.asPoint3f() }); - faces.add(new Point3f[] { c.asPoint3f(), b.asPoint3f(), d.asPoint3f() }); - faces.add(new Point3f[] { d.asPoint3f(), a.asPoint3f(), c.asPoint3f() }); - } - /** * * Perform the 1 -> 4 bistellar flip. This produces 4 new tetrahedron from the @@ -749,12 +785,12 @@ public OrientedFace getFace(Vertex v) { return getFace(ordinalOf(v)); } - public List getFacesCoordinates() { - var faces = new ArrayList(); - faces.add(new Point3f[] { a.asPoint3f(), d.asPoint3f(), b.asPoint3f() }); - faces.add(new Point3f[] { b.asPoint3f(), c.asPoint3f(), a.asPoint3f() }); - faces.add(new Point3f[] { c.asPoint3f(), b.asPoint3f(), d.asPoint3f() }); - faces.add(new Point3f[] { d.asPoint3f(), a.asPoint3f(), c.asPoint3f() }); + public List getFaces() { + List faces = new ArrayList<>(); + faces.add(new Vertex[] { a, d, b }); + faces.add(new Vertex[] { b, c, a }); + faces.add(new Vertex[] { c, b, d }); + faces.add(new Vertex[] { d, a, c }); return faces; } @@ -891,15 +927,15 @@ public V ordinalOf(Vertex v) { } /** - * Answer 1 if the query point is positively oriented with respect to the face - * opposite the vertex, -1 if negatively oriented, 0 if the query point is + * Answer > 0 if the query point is positively oriented with respect to the face + * opposite the vertex, < 0 if negatively oriented, 0 if the query point is * coplanar to the face * * @param face * @param query * @return */ - public int orientationWrt(V face, Vertex query) { + public int orientationWrt(V face, Tuple3d query) { switch (face) { case A: return orientationWrtCBD(query); @@ -915,14 +951,14 @@ public int orientationWrt(V face, Vertex query) { } /** - * Answer 1 if the query point is positively oriented with respect to the face - * ADB, -1 if negatively oriented, 0 if the query point is coplanar to the face + * Answer > 0 if the query point is positively oriented with respect to the face + * ADB, < 0 if negatively oriented, 0 if the query point is coplanar to the face * * @param query * @return */ - public int orientationWrtADB(Vertex query) { - return query.orientation(a, d, b); + public int orientationWrtADB(Tuple3d query) { + return orientation(query, a, d, b); } /** @@ -932,8 +968,8 @@ public int orientationWrtADB(Vertex query) { * @param query * @return */ - public int orientationWrtBCA(Vertex query) { - return query.orientation(b, c, a); + public int orientationWrtBCA(Tuple3d query) { + return orientation(query, b, c, a); } /** @@ -943,8 +979,8 @@ public int orientationWrtBCA(Vertex query) { * @param query * @return */ - public int orientationWrtCBD(Vertex query) { - return query.orientation(c, b, d); + public int orientationWrtCBD(Tuple3d query) { + return orientation(query, c, b, d); } /** @@ -954,8 +990,8 @@ public int orientationWrtCBD(Vertex query) { * @param query * @return */ - public int orientationWrtDAC(Vertex query) { - return query.orientation(d, a, c); + public int orientationWrtDAC(Tuple3d query) { + return orientation(query, d, a, c); } public void removeAnyDegenerateTetrahedronPair() { @@ -1027,10 +1063,6 @@ protected void children(Stack stack, Set processed) { * Clean up the pointers */ void delete() { - a.deleteAdjacent(); - b.deleteAdjacent(); - c.deleteAdjacent(); - d.deleteAdjacent(); nA = nB = nC = nD = null; a = b = c = d = null; } @@ -1055,6 +1087,68 @@ boolean isDeleted() { return a == null; } + /** + * visit the receiver and push unvisited tetrahedrons around the supplied vertex + * + * @param vC - the center vertex + * @param visitor - the star visitor + * @param stack - the stack of visitations + */ + void visit(Vertex vC, StarVisitor visitor, Stack stack, Set visited) { + switch (ordinalOf(vC)) { + case A: + visitor.visit(A, this, c, b, d); + if (nC != null) { + stack.push(nC); + } + if (nB != null) { + stack.push(nC); + } + if (nD != null) { + stack.push(nD); + } + break; + case B: + visitor.visit(B, this, d, a, c); + if (nD != null) { + stack.push(nD); + } + if (nA != null) { + stack.push(nA); + } + if (nC != null) { + stack.push(nC); + } + break; + case C: + visitor.visit(C, this, a, d, b); + if (nA != null) { + stack.push(nA); + } + if (nD != null) { + stack.push(nD); + } + if (nB != null) { + stack.push(nB); + } + break; + case D: + visitor.visit(D, this, b, c, a); + if (nB != null) { + stack.push(nB); + } + if (nA != null) { + stack.push(nB); + } + if (nC != null) { + stack.push(nC); + } + break; + default: + throw new IllegalArgumentException("Invalid center vertex: " + vC); + } + } + /** * Answer the canonical ordinal of the opposite vertex of the neighboring * tetrahedron @@ -1159,13 +1253,13 @@ void setNeighborD(Tetrahedron t) { * @param axis * @param face */ - void traverseVoronoiFace(Tetrahedron origin, Tetrahedron from, Vertex vC, Vertex axis, List face) { + void traverseVoronoiFace(Tetrahedron origin, Tetrahedron from, Vertex vC, Vertex axis, List face) { if (origin == this) { return; } double[] center = new double[3]; centerSphere(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, d.x, d.y, d.z, center); - face.add(new Point3f((float) center[0], (float) center[1], (float) center[2])); + face.add(new Point3d(center[0], center[1], center[2])); V next = VORONOI_FACE_NEXT[ordinalOf(from).ordinal()][ordinalOf(vC).ordinal()][ordinalOf(axis).ordinal()]; Tetrahedron t = getNeighbor(next); if (t != null) { @@ -1183,17 +1277,17 @@ void traverseVoronoiFace(Tetrahedron origin, Tetrahedron from, Vertex vC, Vertex * @param axis * @param face */ - void traverseVoronoiFace(Vertex vC, Vertex axis, List faces) { - ArrayList face = new ArrayList<>(); + void traverseVoronoiFace(Vertex vC, Vertex axis, List faces) { + ArrayList face = new ArrayList<>(); double[] center = new double[3]; centerSphere(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, d.x, d.y, d.z, center); - face.add(new Point3f((float) center[0], (float) center[1], (float) center[2])); + face.add(new Point3d(center[0], center[1], center[2])); V v = VORONOI_FACE_ORIGIN[ordinalOf(vC).ordinal()][ordinalOf(axis).ordinal()]; Tetrahedron next = getNeighbor(v); if (next != null) { next.traverseVoronoiFace(this, this, vC, axis, face); } - faces.add(face.toArray(new Point3f[face.size()])); + faces.add(face.toArray(new Point3d[face.size()])); } /** @@ -1203,70 +1297,13 @@ void traverseVoronoiFace(Vertex vC, Vertex axis, List faces) { * @param visitor - the visitor to invoke for each tetrahedron in the star */ void visitStar(Vertex vC, StarVisitor visitor) { - IdentitySet visited = new IdentitySet<>(10); - visitStar(vC, visitor, visited); - } - - /** - * Visit the star tetrahedra set of the of the center vertex - * - * @param vC - the center vertex - * @param visitor - the visitor to invoke for each tetrahedron in the star - * @param visited - the set of previously visited tetrahedra - */ - void visitStar(Vertex vC, StarVisitor visitor, IdentitySet visited) { - if (visited.add(this)) { - switch (ordinalOf(vC)) { - case A: - visitor.visit(A, this, c, b, d); - if (nC != null) { - nC.visitStar(vC, visitor, visited); - } - if (nB != null) { - nB.visitStar(vC, visitor, visited); - } - if (nD != null) { - nD.visitStar(vC, visitor, visited); - } - break; - case B: - visitor.visit(B, this, d, a, c); - if (nD != null) { - nD.visitStar(vC, visitor, visited); - } - if (nA != null) { - nA.visitStar(vC, visitor, visited); - } - if (nC != null) { - nC.visitStar(vC, visitor, visited); - } - break; - case C: - visitor.visit(C, this, a, d, b); - if (nA != null) { - nA.visitStar(vC, visitor, visited); - } - if (nD != null) { - nD.visitStar(vC, visitor, visited); - } - if (nB != null) { - nB.visitStar(vC, visitor, visited); - } - break; - case D: - visitor.visit(D, this, b, c, a); - if (nB != null) { - nB.visitStar(vC, visitor, visited); - } - if (nA != null) { - nA.visitStar(vC, visitor, visited); - } - if (nC != null) { - nC.visitStar(vC, visitor, visited); - } - break; - default: - throw new IllegalArgumentException("Invalid center vertex: " + vC); + Set tetrahedrons = new IdentitySet<>(10); + var stack = new Stack(); + stack.push(this); + while (!stack.isEmpty()) { + var t = stack.pop(); + if (tetrahedrons.add(t)) { + t.visit(vC, visitor, stack, tetrahedrons); } } } diff --git a/core/src/main/java/com/hellblazer/delaunay/Vertex.java b/core/src/main/java/com/hellblazer/delaunay/Vertex.java index 5d53d4e..607bd23 100644 --- a/core/src/main/java/com/hellblazer/delaunay/Vertex.java +++ b/core/src/main/java/com/hellblazer/delaunay/Vertex.java @@ -19,21 +19,36 @@ package com.hellblazer.delaunay; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; import java.util.Random; +import java.util.Set; -import javax.vecmath.Point3f; +import javax.vecmath.Point3d; +import javax.vecmath.Tuple3d; +import javax.vecmath.Vector3d; /** * * @author Hal Hildebrand * */ -public class Vertex { +public class Vertex extends Vector3d { /** * Minimal zero */ - static final double EPSILON = Math.pow(10D, -20D); - static final Vertex ORIGIN = new Vertex(0, 0, 0); + static final double EPSILON = Math.pow(10D, -20D); + static final Point3d ORIGIN = new Point3d(0, 0, 0); + private static final long serialVersionUID = 1L; + + public static double determinant(Tuple3d a, Tuple3d b, Tuple3d c) { + return a.x * b.y * c.z + b.x * c.y * a.z + c.x * a.y * b.z - b.x * a.y * c.z - c.x * b.y * a.z + - a.x * c.y * b.z; + } /** * Create some random points in a sphere @@ -44,9 +59,9 @@ public class Vertex { * @param inSphere * @return */ - public static Vertex[] getRandomPoints(Random random, int numberOfPoints, double radius, boolean inSphere) { + public static Point3d[] getRandomPoints(Random random, int numberOfPoints, double radius, boolean inSphere) { double radiusSquared = radius * radius; - Vertex ourPoints[] = new Vertex[numberOfPoints]; + Point3d ourPoints[] = new Point3d[numberOfPoints]; for (int i = 0; i < ourPoints.length; i++) { if (inSphere) { do { @@ -60,6 +75,14 @@ public static Vertex[] getRandomPoints(Random random, int numberOfPoints, double return ourPoints; } + public static double pseudoOrientation(Tuple3d a, Tuple3d b, Tuple3d c, Tuple3d d) { + var b1 = new Point3d(b); + b1.sub(c); + var c1 = new Point3d(b); + c1.sub(d); + return determinant(a, b1, c1); + } + /** * Generate a bounded random double * @@ -88,47 +111,34 @@ public static double random(Random random, double min, double max) { * @param max * @return */ - public static Vertex randomPoint(Random random, double min, double max) { - return new Vertex(random(random, min, max), random(random, min, max), random(random, min, max)); + public static Point3d randomPoint(Random random, double min, double max) { + return new Point3d(random(random, min, max), random(random, min, max), random(random, min, max)); } - public final double x; - public final double y; - public final double z; - /** * One of the tetrahedra adjacent to the vertex */ private Tetrahedron adjacent; - /** - * The number of tetrahedra adjacent to the vertex - */ - private int order = 0; - - public Vertex(double i, double j, double k) { + Vertex(double i, double j, double k) { x = i; y = j; z = k; } - public Vertex(double i, double j, double k, double scale) { + Vertex(double i, double j, double k, double scale) { this(i * scale, j * scale, k * scale); } - public Point3f asPoint3f() { - return new Point3f((float) x, (float) y, (float) z); + Vertex(Tuple3d p) { + this(p.x, p.y, p.z); } - /** - * Account for the deletion of an adjacent tetrahedron. - */ - public final void deleteAdjacent() { - order--; - assert order >= 0; + public double determinant(Tuple3d b, Tuple3d c) { + return x * b.y * c.z + b.x * c.y * z + c.x * y * b.z - b.x * y * c.z - c.x * b.y * z - x * c.y * b.z; } - public final double distanceSquared(Vertex p1) { + public final double distanceSquared(Tuple3d p1) { double dx, dy, dz; dx = x - p1.x; @@ -137,11 +147,6 @@ public final double distanceSquared(Vertex p1) { return dx * dx + dy * dy + dz * dz; } - public void freshenAdjacent(Tetrahedron tetrahedron) { - if (adjacent == null || adjacent.isDeleted()) - adjacent = tetrahedron; - } - /** * Answer one of the adjacent tetrahedron * @@ -151,15 +156,64 @@ public final Tetrahedron getAdjacent() { return adjacent; } + public LinkedList getEars() { + assert adjacent != null; + EarSet aggregator = new EarSet(); + adjacent.visitStar(this, aggregator); + return aggregator.getEars(); + } + /** - * Answer the number of tetrahedra adjacent to the receiver vertex in the - * tetrahedralization - *

+ * Answer the collection of neighboring vertices around the indicated vertex. * - * @return + * @param v - the vertex determining the neighborhood + * @return the collection of neighboring vertices */ - public final int getOrder() { - return order; + public Collection getNeighbors() { + assert adjacent != null; + + final Set neighbors = new IdentitySet<>(); + adjacent.visitStar(this, (vertex, t, x, y, z) -> { + neighbors.add(x); + neighbors.add(y); + neighbors.add(z); + }); + return neighbors; + } + + public Deque getStar() { + assert adjacent != null; + + final Deque star = new ArrayDeque<>(); + adjacent.visitStar(this, (vertex, t, x, y, z) -> { + star.push(t.getFace(vertex)); + }); + return star; + } + + /** + * Answer the faces of the voronoi region around the receiver + * + * @param v - the vertex of interest + * @return the list of faces defining the voronoi region defined by the receiver + */ + public List getVoronoiRegion() { + assert adjacent != null; + + final List faces = new ArrayList<>(); + Set neighbors = new IdentitySet<>(10); + adjacent.visitStar(this, (vertex, t, x, y, z) -> { + if (neighbors.add(x)) { + t.traverseVoronoiFace(this, x, faces); + } + if (neighbors.add(y)) { + t.traverseVoronoiFace(this, y, faces); + } + if (neighbors.add(z)) { + t.traverseVoronoiFace(this, z, faces); + } + }); + return faces; } /** @@ -176,7 +230,7 @@ public final int getOrder() { * cospherical */ - public final int inSphere(Vertex a, Vertex b, Vertex c, Vertex d) { + public final int inSphere(Tuple3d a, Tuple3d b, Tuple3d c, Tuple3d d) { double result = Geometry.inSphere(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, d.x, d.y, d.z, x, y, z); if (result > 0.0) { return 1; @@ -184,7 +238,30 @@ public final int inSphere(Vertex a, Vertex b, Vertex c, Vertex d) { return -1; } return 0; + } + /** + * Answer the maximum fraction of delta displacement the receiver before a + * topological event occurs. + * + * @param delta - the displacement delta of the receiver + * @return l - l <= 1 if a topological event will occur at this + (l * delta), l + * > 1 if no topological event will occur + */ + public double maxStep(Tuple3d delta) { + double[] min = new double[] { Double.MAX_VALUE }; + var target = new Point3d(); + target.add(this, delta); + adjacent.visitStar(this, (vertex, t, a, b, c) -> { + var pseudo = Geometry.leftOfPlaneFast(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, x, y, z); + var newPos = new Vertex(this); + newPos.add(delta); + var pseudoDelta = Geometry.leftOfPlaneFast(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, newPos.x, newPos.y, + newPos.z); + var l = pseudo / Math.abs(pseudoDelta); + min[0] = Math.min(l, min[0]); + }); + return min[0]; } /** @@ -197,7 +274,7 @@ public final int inSphere(Vertex a, Vertex b, Vertex c, Vertex d) { * @return +1 if the orientation of the query point is positive with respect to * the plane, -1 if negative and 0 if the test point is coplanar */ - public final int orientation(Vertex a, Vertex b, Vertex c) { + public final int orientation(Tuple3d a, Tuple3d b, Tuple3d c) { double result = Geometry.leftOfPlane(a.x, a.y, a.z, b.x, b.y, b.z, c.x, c.y, c.z, x, y, z); if (result > 0.0) { return 1; @@ -207,12 +284,24 @@ public final int orientation(Vertex a, Vertex b, Vertex c) { return 0; } - /** - * Reset the state associated with a tetrahedralization. - */ - public final void reset() { - adjacent = null; - order = 0; + public double pseudoOrientation(Tuple3d b, Tuple3d c, Tuple3d d) { + var a1 = new Point3d(this); + a1.sub(b); + var b1 = new Point3d(b); + b1.sub(c); + var c1 = new Point3d(b); + c1.sub(d); + return determinant(a1, b1, c1); + } + + @Override + public String toString() { + return "{" + x + ", " + y + ", " + z + "}"; + } + + void freshenAdjacent(Tetrahedron tetrahedron) { + if (adjacent == null || adjacent.isDeleted()) + adjacent = tetrahedron; } /** @@ -221,14 +310,8 @@ public final void reset() { * * @param tetrahedron */ - public final void setAdjacent(Tetrahedron tetrahedron) { - order++; + final void setAdjacent(Tetrahedron tetrahedron) { adjacent = tetrahedron; } - @Override - public String toString() { - return "{" + x + ", " + y + ", " + z + "}"; - } - } diff --git a/core/src/main/java/com/hellblazer/delaunay/sturm/ExpInterval.java b/core/src/main/java/com/hellblazer/delaunay/sturm/ExpInterval.java new file mode 100644 index 0000000..31c6472 --- /dev/null +++ b/core/src/main/java/com/hellblazer/delaunay/sturm/ExpInterval.java @@ -0,0 +1,48 @@ +/* This file is part of Gralog, Copyright (c) 2016-2018 LaS group, TU Berlin. + * License: https://www.gnu.org/licenses/gpl.html GPL version 3 or later. */ + +package com.hellblazer.delaunay.sturm; + +/** + * Represents intervals for root isolation. The interval + */ +public class ExpInterval implements Interval, Comparable { + + double c; + int k; + + public ExpInterval(int k, double c) { + this.k = k; + this.c = c; + } + + @Override + public int compareTo(ExpInterval o) { + return (int) Math.signum(c / (1 << k) - o.c / (1 << o.k)); + } + + /** + * Tests if a real number is in the interval + * + * @return + */ + @Override + public boolean contains(double t) { + return t > lowerBound() && t < upperBound(); + } + + @Override + public double lowerBound() { + return c / (1 << k); + } + + @Override + public String toString() { + return String.format("(%.2f,%.2f)", c / (1 << k), (c + 1) / (1 << k)); + } + + @Override + public double upperBound() { + return (c + 1) / (1 << k); + } +} diff --git a/core/src/main/java/com/hellblazer/delaunay/sturm/Interval.java b/core/src/main/java/com/hellblazer/delaunay/sturm/Interval.java new file mode 100644 index 0000000..af98ca0 --- /dev/null +++ b/core/src/main/java/com/hellblazer/delaunay/sturm/Interval.java @@ -0,0 +1,13 @@ +/* This file is part of Gralog, Copyright (c) 2016-2018 LaS group, TU Berlin. + * License: https://www.gnu.org/licenses/gpl.html GPL version 3 or later. */ + +package com.hellblazer.delaunay.sturm; + +public interface Interval { + + boolean contains(double t); + + double lowerBound(); + + double upperBound(); +} diff --git a/core/src/main/java/com/hellblazer/delaunay/sturm/Polynomial.java b/core/src/main/java/com/hellblazer/delaunay/sturm/Polynomial.java new file mode 100644 index 0000000..e52f32c --- /dev/null +++ b/core/src/main/java/com/hellblazer/delaunay/sturm/Polynomial.java @@ -0,0 +1,39 @@ +/* This file is part of Gralog, Copyright (c) 2016-2018 LaS group, TU Berlin. + * License: https://www.gnu.org/licenses/gpl.html GPL version 3 or later. */ + +package com.hellblazer.delaunay.sturm; + +import java.util.Arrays; + +/** + * + */ +public class Polynomial { + + public double[] coeff; + public int n; + + /** + * ax^5+.....+f + * + * Coefficient to largest monomial first. + */ + public Polynomial(double... params) { + this.n = params.length - 1; + this.coeff = params; + } + + public double eval(double x) { + double result = 0; + for (int i = 0; i < n + 1; i++) { + result = coeff[i] + (x * result); + } + return result; + } + + @Override + public String toString() { + return Arrays.toString(coeff); + } + +} diff --git a/core/src/main/java/com/hellblazer/delaunay/sturm/SturmRootIsolator.java b/core/src/main/java/com/hellblazer/delaunay/sturm/SturmRootIsolator.java new file mode 100644 index 0000000..4ea7e52 --- /dev/null +++ b/core/src/main/java/com/hellblazer/delaunay/sturm/SturmRootIsolator.java @@ -0,0 +1,291 @@ +/* This file is part of Gralog, Copyright (c) 2016-2018 LaS group, TU Berlin. + * License: https://www.gnu.org/licenses/gpl.html GPL version 3 or later. */ + +package com.hellblazer.delaunay.sturm; + +import java.util.ArrayList; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Queue; + +//TODO: Use simple interval pruning to reduce intervals. Maybe implement a different findRootsDN, or prune roots +//in the bezier class + +/** + * This class implements algorithms for isolating the roots of univariate + * polynomials by using Sturm Sequence Method based algorithms. + * + * A recent benchmark comparing performance of several root solvers on multiple + * kinds of high-order polynomials using the descartes method can be found below + * + * @see Implementation of k + * hybrid arithmetic strategy + * @see Reference + * for ANewDesc algorithm + * @see High-performance implementation + * of ANewDesc and RS hybrid + * @see Efficient isolation of + * polynomial's real roots + */ +public final class SturmRootIsolator { + + private static final double EPS = 0.005; + + /** + * Returns a list of isolating intervals for a given polynomial. The intervals + * are found by constructing a sturm sequence for the given polynomial and then + * doing a binary search on the interval [0, 1) + */ + public static List findIntervals(Polynomial p) { + return findIntervals(sturmSequence(p)); + } + + /** + * Computes all isolating intervals with a given Sturm sequence between 0 and 1 + */ + public static List findIntervals(Polynomial[] sequence) { + int sigma0 = countSignChanges(sequence, 0); + int sigma1 = countSignChanges(sequence, 1); + int max = sigma0 - sigma1; + + Queue intervals = new PriorityQueue<>(); + List isolation = new ArrayList<>(); + + intervals.add(new ExpInterval(1, 0)); + intervals.add(new ExpInterval(1, 1)); + + while (!intervals.isEmpty()) { + ExpInterval v = intervals.poll(); + int s = countSturmRoots(sequence, v); + if (s == 1) { + isolation.add(v); + } else if (s > 1) { + intervals.add(new ExpInterval(v.k + 1, 2 * v.c)); + intervals.add(new ExpInterval(v.k + 1, 2 * v.c + 1)); + } + } + return isolation; + } + + public static double findRoot(Polynomial p, double from, double to, int iterations) { + double m; + double tmp; + boolean descending = p.eval(from) > 0; + for (int i = 0; i < iterations; i++) { + m = (to + from) / 2; + tmp = p.eval(m); + if (Math.abs(tmp) < EPS) { + return m; + } else { + if (descending) { + if (tmp > 0) { + from = m; + } else { + to = m; + } + } else { + if (tmp < 0) { + from = m; + } else { + to = m; + } + } + + } + } + + return (to + from) / 2; + } + + /** + * Warning: + * + * This algorithm only finds roots where the derivative is negative! + */ + public static double findRootDN(Polynomial p, double from, double to) { + return findRootDN(p, from, to, 10); + } + + public static double findRootDN(Polynomial p, double from, double to, int iterations) { + double m; + double tmp; + for (int i = 0; i < iterations; i++) { + m = (to + from) / 2; + tmp = p.eval(m); + if (Math.abs(tmp) < EPS) { + return m; + } else if (tmp > 0) { + from = m; + } else { + to = m; + } + } + + return (to + from) / 2; + } + + public static double[] findRoots(Polynomial p, List intervals, int iterations) { + double[] roots = new double[intervals.size()]; + for (int i = 0; i < roots.length; i++) { + Interval interval = intervals.get(i); + roots[i] = findRoot(p, interval.lowerBound(), interval.upperBound(), iterations); + } + return roots; + } + + /** + * Returns an array of root approximations of a polynomial. The method first + * constructs isolating intervals by using Sturm sequences and then applies + * Newton approximation to robustly find every root of the polynomial. + * + * If you want to use your own subdivision algorithm, use the overloaded method + * that accepts a list of intervals. You might want to implement your own + * Interval class as well + * + * @see Interval + */ + public static double[] findRootsDN(Polynomial p) { + return findRootsDN(p, findIntervals(p)); + } + + /** + * Returns an array of root approximations of a polynomial by applying Newton to + * each given isolation interval. + * + * You can find intervals with a number of methods e.g. Sturm Sequences, + * Descartes method, cone testing etc.. + * + * @param p The polynomial + * @param intervals Root-isolating intervals of the polynomial p + * @return A double array of root approximations + * @see ExpInterval Note the semantics of the bounds + */ + public static double[] findRootsDN(Polynomial p, List intervals) { // only descending roots + double[] roots = new double[intervals.size()]; + for (int i = 0; i < roots.length; i++) { + Interval interval = intervals.get(i); + roots[i] = findRootDN(p, interval.lowerBound(), interval.upperBound()); + } + return roots; + } + + public static Polynomial[] sturmSequence(double... coeff) { + return sturmSequence(new Polynomial(coeff)); + } + + /** + * Computes k Sturm sequence for k given polynomial. The sequence can be used to + * identify intervals that isolate distinct roots. + *

+ * THEOREM: LetS ={p0 =p,p1,...,pm}be k Sturm sequence, where p is k square-free + * polynomial,and let σ(S,x) denote the number of sign changes (zeros are not + * counted) in the sequence S. Then for two real numbers k < b, the number of + * zeros of p in the open interval(k,b)is σ(S,k)−σ(S,b). + *

+ * An optimized version for degree 5 polynomials is available + *

+ * Calculation is based on the paper linked below. It calculates the Sturm + * sequence in k robust manner (which is necessary, since iteratively evaluating + * k Sturm sequence for k given x has k very high precision requirement.) + * + * @see reference + */ + public static Polynomial[] sturmSequence(Polynomial p) { + + int m = p.coeff.length; + + Polynomial[] sequence = new Polynomial[m]; + double[][] a = new double[m][]; + + for (int i = 0; i < m; i++) { + a[i] = new double[m - i]; + } + double[] matrT = new double[m]; + double[] matrM = new double[m]; + + // to press k[0] and k[1] into the same loop + a[0][p.n] = p.coeff[p.n]; + for (int j = 0; j < m - 1; j++) { + a[0][j] = p.coeff[j]; + a[1][j] = (p.n - j) * p.coeff[j]; + } + + sequence[0] = new Polynomial(a[0]); + sequence[1] = new Polynomial(a[1]); + + for (int i = 2; i < m; i++) { + matrT[i] = a[i - 2][0] / a[i - 1][0]; + matrM[i] = (a[i - 2][1] - matrT[i] * a[i - 1][1]) / a[i - 1][0]; + for (int j = 0; j < m - i - 1; j++) { + a[i][j] = -a[i - 2][j + 2] + matrM[i] * a[i - 1][j + 1] + matrT[i] * a[i - 1][j + 2]; + } + // the last actual iteration of the previous loop with j=m-i-1 uses k[i-1][j+2], + // which + // is not defined and therefore zero. + a[i][m - i - 1] = -a[i - 2][m - i + 1] + matrM[i] * a[i - 1][m - i]; + + // after i-th iteration, sturm sequence coefficients are in k[i] + sequence[i] = new Polynomial(a[i]); + } + + return sequence; + + } + + /** + * Counts sign changes of an array of coefficients + */ + private static int countSignChanges(double... coeff) { + int count = 0; + double sign = Math.signum(coeff[0]); + double signNew; + for (int i = 0; i < coeff.length; i++) { + if (coeff[i] == 0) { + continue; + } + signNew = Math.signum(coeff[i]); + if (signNew != sign) { + count++; + } + sign = signNew; + } + return count; + } + + // computes sign change count on k sturm sequence, evaluated at t + private static int countSignChanges(Polynomial[] sequence, double t) { + int count = 0; + + double sign = Math.signum(sequence[0].eval(t)); + + for (int i = 0; i < sequence.length; i++) { + double tmp = sequence[i].eval(t); + if (tmp == 0) { + continue; + } + if (Math.signum(tmp) != sign) { + count++; + sign *= -1; + } + } + + return count; + } + + private static int countSturmRoots(Polynomial[] sequence, ExpInterval v) { + int a = countSignChanges(sequence, v.lowerBound()); + int b = countSignChanges(sequence, v.upperBound()); + return a - b; + } + + private static int countSturmRoots(Polynomial[] sequence, int k, double c) { + int a = countSignChanges(sequence, c / (1 << k)); + int b = countSignChanges(sequence, (c + 1) / (1 << k)); + return a - b; + } + + private SturmRootIsolator() { + } +} diff --git a/core/src/test/java/com/hellblazer/delaunay/Examples.java b/core/src/test/java/com/hellblazer/delaunay/Examples.java new file mode 100644 index 0000000..eb76f48 --- /dev/null +++ b/core/src/test/java/com/hellblazer/delaunay/Examples.java @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2008 Hal Hildebrand. All rights reserved. + * + * This file is part of the 3D Incremental Voronoi GUI + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.hellblazer.delaunay; + +import java.util.ArrayList; + +import javax.vecmath.Point3d; + +/** + * + * @author Hal Hildebrand + * + */ + +public class Examples { + + public static Point3d[] getCubicCrystalStructure() { + ArrayList list = new ArrayList<>(); + list.add(new Point3d(-0.89999799999999996D, -0.89999200000000001D, -0.900003D)); + list.add(new Point3d(-0.90000199999999997D, -0.90000800000000003D, -6.9999999999999999E-06D)); + list.add(new Point3d(-0.89999499999999999D, -0.90000199999999997D, 0.900003D)); + list.add(new Point3d(-0.89999099999999999D, 5.0000000000000004E-06D, -0.89999099999999999D)); + list.add(new Point3d(-0.89999399999999996D, 9.9999999999999995E-07D, 5.0000000000000004E-06D)); + list.add(new Point3d(-0.90000800000000003D, 5.0000000000000004E-06D, 0.90000500000000005D)); + list.add(new Point3d(-0.89999499999999999D, 0.89999099999999999D, -0.89999600000000002D)); + list.add(new Point3d(-0.90000100000000005D, 0.90000000000000002D, -1.9999999999999999E-06D)); + list.add(new Point3d(-0.89999499999999999D, 0.90000199999999997D, 0.89999899999999999D)); + list.add(new Point3d(-6.0000000000000002E-06D, -0.89999600000000002D, -0.90000599999999997D)); + list.add(new Point3d(-6.0000000000000002E-06D, -0.900007D, -6.0000000000000002E-06D)); + list.add(new Point3d(-3.0000000000000001E-06D, -0.90000100000000005D, 0.89999600000000002D)); + list.add(new Point3d(3.9999999999999998E-06D, 0.0D, -0.89999399999999996D)); + list.add(new Point3d(-9.0000000000000002E-06D, 5.0000000000000004E-06D, 1.0000000000000001E-05D)); + list.add(new Point3d(-6.0000000000000002E-06D, -1.9999999999999999E-06D, 0.89999799999999996D)); + list.add(new Point3d(9.0000000000000002E-06D, 0.89999600000000002D, -0.90000599999999997D)); + list.add(new Point3d(1.0000000000000001E-05D, 0.90000100000000005D, 3.9999999999999998E-06D)); + list.add(new Point3d(-6.9999999999999999E-06D, 0.90000899999999995D, 0.89999600000000002D)); + list.add(new Point3d(0.89999799999999996D, -0.90000800000000003D, -0.89999600000000002D)); + list.add(new Point3d(0.90000500000000005D, -0.89999899999999999D, -1.9999999999999999E-06D)); + list.add(new Point3d(0.89999600000000002D, -0.89999099999999999D, 0.90000199999999997D)); + list.add(new Point3d(0.89999499999999999D, 9.9999999999999995E-07D, -0.89999700000000005D)); + list.add(new Point3d(0.90000500000000005D, -5.0000000000000004E-06D, -3.9999999999999998E-06D)); + list.add(new Point3d(0.89999799999999996D, -3.9999999999999998E-06D, 0.89999899999999999D)); + list.add(new Point3d(0.90000599999999997D, 0.900003D, -0.89999600000000002D)); + list.add(new Point3d(0.89999600000000002D, 0.89999899999999999D, -6.9999999999999999E-06D)); + list.add(new Point3d(0.90000400000000003D, 0.89999499999999999D, 0.900003D)); + list.add(new Point3d(-0.44999499999999998D, -0.44999099999999997D, -0.45001000000000002D)); + list.add(new Point3d(-0.45000200000000001D, -0.45000499999999999D, 0.44999499999999998D)); + list.add(new Point3d(-0.449992D, 0.44999099999999997D, -0.449992D)); + list.add(new Point3d(-0.44999499999999998D, 0.45000600000000002D, 0.44999099999999997D)); + list.add(new Point3d(0.45000099999999998D, -0.44999600000000001D, -0.44999600000000001D)); + list.add(new Point3d(0.44999800000000001D, -0.45000899999999999D, 0.44999299999999998D)); + list.add(new Point3d(0.44999400000000001D, 0.44999499999999998D, -0.45000800000000002D)); + list.add(new Point3d(0.45000800000000002D, 0.44999600000000001D, 0.45000699999999999D)); + return list.toArray(new Point3d[list.size()]); + } + + public static Point3d[] getGrid() { + ArrayList list; + list = new ArrayList<>(); + list.add(new Point3d(-0.74999800000000005D, -0.74999199999999999D, -0.75000299999999998D)); + list.add(new Point3d(-0.75000199999999995D, -0.75000800000000001D, -0.25000699999999998D)); + list.add(new Point3d(-0.74999499999999997D, -0.75000199999999995D, 0.25000299999999998D)); + list.add(new Point3d(-0.74999099999999996D, -0.74999499999999997D, 0.75000900000000004D)); + list.add(new Point3d(-0.74999400000000005D, -0.249999D, -0.74999499999999997D)); + list.add(new Point3d(-0.75000800000000001D, -0.24999499999999999D, -0.24999499999999999D)); + list.add(new Point3d(-0.74999499999999997D, -0.25000899999999998D, 0.250004D)); + list.add(new Point3d(-0.75000100000000003D, -0.25D, 0.74999800000000005D)); + list.add(new Point3d(-0.74999499999999997D, 0.250002D, -0.75000100000000003D)); + list.add(new Point3d(-0.75000599999999995D, 0.250004D, -0.25000600000000001D)); + list.add(new Point3d(-0.75000599999999995D, 0.24999299999999999D, 0.24999399999999999D)); + list.add(new Point3d(-0.75000299999999998D, 0.249999D, 0.749996D)); + list.add(new Point3d(-0.749996D, 0.75D, -0.74999400000000005D)); + list.add(new Point3d(-0.75000900000000004D, 0.75000500000000003D, -0.24998999999999999D)); + list.add(new Point3d(-0.75000599999999995D, 0.74999800000000005D, 0.249998D)); + list.add(new Point3d(-0.74999099999999996D, 0.749996D, 0.74999400000000005D)); + list.add(new Point3d(-0.24998999999999999D, -0.74999899999999997D, -0.749996D)); + list.add(new Point3d(-0.25000699999999998D, -0.74999099999999996D, -0.250004D)); + list.add(new Point3d(-0.250002D, -0.75000800000000001D, 0.250004D)); + list.add(new Point3d(-0.24999499999999999D, -0.74999899999999997D, 0.74999800000000005D)); + list.add(new Point3d(-0.250004D, -0.24999099999999999D, -0.74999800000000005D)); + list.add(new Point3d(-0.25000499999999998D, -0.249999D, -0.249997D)); + list.add(new Point3d(-0.24999499999999999D, -0.25000499999999998D, 0.249996D)); + list.add(new Point3d(-0.250002D, -0.250004D, 0.74999899999999997D)); + list.add(new Point3d(-0.24999399999999999D, 0.25000299999999998D, -0.749996D)); + list.add(new Point3d(-0.250004D, 0.249999D, -0.25000699999999998D)); + list.add(new Point3d(-0.249996D, 0.24999499999999999D, 0.25000299999999998D)); + list.add(new Point3d(-0.24999499999999999D, 0.25000899999999998D, 0.74999000000000005D)); + list.add(new Point3d(-0.250002D, 0.74999499999999997D, -0.75000500000000003D)); + list.add(new Point3d(-0.24999199999999999D, 0.74999099999999996D, -0.24999199999999999D)); + list.add(new Point3d(-0.24999499999999999D, 0.75000599999999995D, 0.24999099999999999D)); + list.add(new Point3d(-0.249999D, 0.750004D, 0.750004D)); + list.add(new Point3d(0.249998D, -0.75000900000000004D, -0.75000699999999998D)); + list.add(new Point3d(0.24999399999999999D, -0.75000500000000003D, -0.25000800000000001D)); + list.add(new Point3d(0.25000800000000001D, -0.750004D, 0.25000699999999998D)); + list.add(new Point3d(0.25000099999999997D, -0.75D, 0.75000800000000001D)); + list.add(new Point3d(0.250002D, -0.25000699999999998D, -0.75000900000000004D)); + list.add(new Point3d(0.249997D, -0.249997D, -0.24999299999999999D)); + list.add(new Point3d(0.249996D, -0.24999499999999999D, 0.25001000000000001D)); + list.add(new Point3d(0.25000800000000001D, -0.25000699999999998D, 0.75000100000000003D)); + list.add(new Point3d(0.24999499999999999D, 0.249996D, -0.749996D)); + list.add(new Point3d(0.249998D, 0.250004D, -0.24999099999999999D)); + list.add(new Point3d(0.249998D, 0.25000099999999997D, 0.25000299999999998D)); + list.add(new Point3d(0.25000099999999997D, 0.24999399999999999D, 0.74999300000000002D)); + list.add(new Point3d(0.25001000000000001D, 0.749996D, -0.75000699999999998D)); + list.add(new Point3d(0.250004D, 0.750004D, -0.25000899999999998D)); + list.add(new Point3d(0.25000800000000001D, 0.74999099999999996D, 0.249996D)); + list.add(new Point3d(0.24999299999999999D, 0.74999000000000005D, 0.75000100000000003D)); + list.add(new Point3d(0.75000299999999998D, -0.74999700000000002D, -0.75000900000000004D)); + list.add(new Point3d(0.74999899999999997D, -0.75000199999999995D, -0.24999399999999999D)); + list.add(new Point3d(0.74999700000000002D, -0.75000599999999995D, 0.249997D)); + list.add(new Point3d(0.75000900000000004D, -0.75000800000000001D, 0.75D)); + list.add(new Point3d(0.75000900000000004D, -0.24999499999999999D, -0.74999499999999997D)); + list.add(new Point3d(0.74999800000000005D, -0.25000899999999998D, -0.250002D)); + list.add(new Point3d(0.75D, -0.250004D, 0.25000699999999998D)); + list.add(new Point3d(0.749996D, -0.25D, 0.749996D)); + list.add(new Point3d(0.75000199999999995D, 0.24999199999999999D, -0.75000500000000003D)); + list.add(new Point3d(0.750004D, 0.25000899999999998D, -0.25D)); + list.add(new Point3d(0.75000500000000003D, 0.25001000000000001D, 0.250002D)); + list.add(new Point3d(0.74999800000000005D, 0.25000699999999998D, 0.75000599999999995D)); + list.add(new Point3d(0.75000599999999995D, 0.75000299999999998D, -0.75D)); + list.add(new Point3d(0.74999199999999999D, 0.74999800000000005D, -0.25000600000000001D)); + list.add(new Point3d(0.74999300000000002D, 0.74999400000000005D, 0.24998999999999999D)); + list.add(new Point3d(0.75000299999999998D, 0.75000699999999998D, 0.75000199999999995D)); + return list.toArray(new Point3d[list.size()]); + } + + public static Point3d[] getWorstCase() { + ArrayList list; + list = new ArrayList<>(); + + list.add(new Point3d(-0.36000100000000002D, 7.9999999999999996E-06D, 0.96000099999999999D)); + list.add(new Point3d(0.120003D, 0.88000900000000004D, 0.120002D)); + list.add(new Point3d(-0.30000100000000002D, 0.0D, 0.900003D)); + list.add(new Point3d(0.100004D, 0.80000899999999997D, 0.100007D)); + list.add(new Point3d(-0.240008D, 7.9999999999999996E-06D, 0.84000399999999997D)); + list.add(new Point3d(0.080005999999999994D, 0.72000699999999995D, 0.080005000000000007D)); + list.add(new Point3d(-0.180009D, 6.0000000000000002E-06D, 0.780003D)); + list.add(new Point3d(0.060006999999999998D, 0.64000500000000005D, 0.060002D)); + list.add(new Point3d(-0.120005D, 3.9999999999999998E-06D, 0.72000900000000001D)); + list.add(new Point3d(0.040003999999999998D, 0.56000300000000003D, 0.040004999999999999D)); + list.add(new Point3d(-0.060003000000000001D, 1.9999999999999999E-06D, 0.66000300000000001D)); + list.add(new Point3d(0.020004000000000001D, 0.48000100000000001D, 0.020001999999999999D)); + list.add(new Point3d(6.0000000000000002E-06D, 9.0000000000000002E-06D, 0.60000600000000004D)); + list.add(new Point3d(6.0000000000000002E-06D, 0.40000799999999997D, 9.0000000000000002E-06D)); + list.add(new Point3d(0.060000999999999999D, 6.9999999999999999E-06D, 0.54000800000000004D)); + list.add(new Point3d(-0.020003D, 0.32000600000000001D, -0.020005999999999999D)); + list.add(new Point3d(0.120007D, 5.0000000000000004E-06D, 0.48000399999999999D)); + list.add(new Point3d(-0.040003999999999998D, 0.240004D, -0.040003999999999998D)); + list.add(new Point3d(0.180008D, 3.0000000000000001E-06D, 0.42000300000000002D)); + list.add(new Point3d(-0.060000999999999999D, 0.16000200000000001D, -0.060002D)); + list.add(new Point3d(0.240007D, 9.9999999999999995E-07D, 0.36000700000000002D)); + list.add(new Point3d(-0.080004000000000006D, 0.080004000000000006D, -0.080008999999999997D)); + list.add(new Point3d(0.30000199999999999D, 1.9999999999999999E-06D, 0.30000100000000002D)); + list.add(new Point3d(-0.10000299999999999D, 3.0000000000000001E-06D, -0.10000199999999999D)); + list.add(new Point3d(0.36000399999999999D, 6.0000000000000002E-06D, 0.240006D)); + list.add(new Point3d(-0.120005D, -0.080004000000000006D, -0.120003D)); + list.add(new Point3d(0.42000599999999999D, 6.9999999999999999E-06D, 0.180009D)); + list.add(new Point3d(-0.14000699999999999D, -0.160001D, -0.14000199999999999D)); + list.add(new Point3d(0.48000799999999999D, 3.0000000000000001E-06D, 0.120003D)); + list.add(new Point3d(-0.16000900000000001D, -0.240006D, -0.16000600000000001D)); + list.add(new Point3d(0.54000099999999995D, 1.9999999999999999E-06D, 0.060000600000000001D)); + list.add(new Point3d(-0.180002D, -0.32000299999999998D, -0.18000099999999999D)); + list.add(new Point3d(0.60000299999999995D, 3.9999999999999998E-06D, 5.0000000000000004E-06D)); + list.add(new Point3d(-0.20000399999999999D, -0.40000599999999997D, -0.20000200000000001D)); + list.add(new Point3d(0.66000499999999995D, 6.9999999999999999E-06D, -0.060003000000000001D)); + list.add(new Point3d(-0.22000600000000001D, -0.48000900000000002D, -0.22000600000000001D)); + list.add(new Point3d(0.72000699999999995D, 7.9999999999999996E-06D, -0.120004D)); + list.add(new Point3d(-0.240008D, -0.56000399999999995D, -0.24000299999999999D)); + list.add(new Point3d(0.78000899999999995D, 5.0000000000000004E-06D, -0.180007D)); + list.add(new Point3d(-0.26000200000000001D, -0.64000699999999999D, -0.26000400000000001D)); + list.add(new Point3d(0.840001D, 7.9999999999999996E-06D, -0.24000199999999999D)); + list.add(new Point3d(-0.280003D, -0.720001D, -0.280005D)); + list.add(new Point3d(0.90000500000000005D, 3.0000000000000001E-06D, -0.30000700000000002D)); + list.add(new Point3d(-0.30000300000000002D, -0.80000499999999997D, -0.30000300000000002D)); + list.add(new Point3d(0.96000099999999999D, 1.9999999999999999E-06D, -0.36000700000000002D)); + list.add(new Point3d(-0.32000899999999999D, -0.88000100000000003D, -0.32000299999999998D)); + return list.toArray(new Point3d[list.size()]); + } +} diff --git a/core/src/test/java/com/hellblazer/delaunay/TestTimeInsert.java b/core/src/test/java/com/hellblazer/delaunay/TestTimeInsert.java index 0bdda9d..c392735 100644 --- a/core/src/test/java/com/hellblazer/delaunay/TestTimeInsert.java +++ b/core/src/test/java/com/hellblazer/delaunay/TestTimeInsert.java @@ -23,6 +23,8 @@ import java.util.Random; +import javax.vecmath.Point3d; + import org.junit.Test; /** @@ -42,15 +44,15 @@ public void testCubic() throws Exception { Tetrahedralization tet = new Tetrahedralization(random); - Vertex[] cubicCrystalStructure = Examples.getCubicCrystalStructure(); - for (Vertex v : cubicCrystalStructure) { + Point3d[] cubicCrystalStructure = Examples.getCubicCrystalStructure(); + for (var v : cubicCrystalStructure) { tet.insert(v); } long now = System.nanoTime(); for (int i = 0; i < iterations; i++) { tet = new Tetrahedralization(random); - for (Vertex v : cubicCrystalStructure) { + for (var v : cubicCrystalStructure) { tet.insert(v); } } @@ -65,15 +67,15 @@ public void testGrid() throws Exception { Tetrahedralization tet = new Tetrahedralization(random); - Vertex[] grid = Examples.getGrid(); - for (Vertex v : grid) { + Point3d[] grid = Examples.getGrid(); + for (var v : grid) { tet.insert(v); } long now = System.nanoTime(); for (int i = 0; i < iterations; i++) { tet = new Tetrahedralization(random); - for (Vertex v : grid) { + for (var v : grid) { tet.insert(v); } } @@ -84,17 +86,17 @@ public void testGrid() throws Exception { @Test public void testLargeRandom() { Random random = new Random(666); - Vertex ourPoints[] = getRandomPoints(random, 600, 1.0D, false); + Point3d ourPoints[] = getRandomPoints(random, 600, 1.0D, false); Tetrahedralization tet = new Tetrahedralization(random); - for (Vertex v : ourPoints) { + for (var v : ourPoints) { tet.insert(v); } long now = System.nanoTime(); for (int i = 0; i < iterations; i++) { tet = new Tetrahedralization(random); - for (Vertex v : ourPoints) { + for (var v : ourPoints) { tet.insert(v); } } @@ -105,17 +107,17 @@ public void testLargeRandom() { @Test public void testSuperLargeRandom() { Random random = new Random(666); - Vertex ourPoints[] = getRandomPoints(random, 6000, 10.0D, false); + Point3d ourPoints[] = getRandomPoints(random, 6000, 10.0D, false); Tetrahedralization tet = new Tetrahedralization(random); - for (Vertex v : ourPoints) { + for (var v : ourPoints) { tet.insert(v); } long now = System.nanoTime(); for (int i = 0; i < 2; i++) { tet = new Tetrahedralization(random); - for (Vertex v : ourPoints) { + for (var v : ourPoints) { tet.insert(v); } } @@ -129,15 +131,15 @@ public void testWorstCase() throws Exception { Tetrahedralization tet = new Tetrahedralization(random); - Vertex[] worstCase = Examples.getWorstCase(); - for (Vertex v : worstCase) { + Point3d[] worstCase = Examples.getWorstCase(); + for (var v : worstCase) { tet.insert(v); } long now = System.nanoTime(); for (int i = 0; i < iterations; i++) { tet = new Tetrahedralization(random); - for (Vertex v : worstCase) { + for (var v : worstCase) { tet.insert(v); } } diff --git a/core/src/test/java/com/hellblazer/delaunay/TestVertex.java b/core/src/test/java/com/hellblazer/delaunay/TestVertex.java deleted file mode 100644 index 96a5341..0000000 --- a/core/src/test/java/com/hellblazer/delaunay/TestVertex.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.hellblazer.delaunay; - -import static junit.framework.Assert.assertEquals; - -import org.junit.Test; - -public class TestVertex { - - @Test - public void testOrientation() { - Vertex[] fourCorners = Tetrahedralization.getFourCorners(); - assertEquals(1, fourCorners[3].orientation(fourCorners[0], fourCorners[1], fourCorners[2])); - assertEquals(-1, fourCorners[3].orientation(fourCorners[1], fourCorners[0], fourCorners[2])); - assertEquals(0, new Vertex(100, 100, 0).orientation(new Vertex(1000, 100000, 0), new Vertex(0, -1456, 0), - new Vertex(-2567, 0, 0))); - assertEquals(1, fourCorners[0].orientation(fourCorners[2], fourCorners[1], fourCorners[3])); - - assertEquals(1, fourCorners[1].orientation(fourCorners[3], fourCorners[0], fourCorners[2])); - - assertEquals(1, fourCorners[2].orientation(fourCorners[0], fourCorners[3], fourCorners[1])); - - assertEquals(1, fourCorners[3].orientation(fourCorners[1], fourCorners[2], fourCorners[0])); - } - - @Test - public void testOrientation2() { - Vertex[] fourCorners = Tetrahedralization.getFourCorners(); - Vertex N = new Vertex(0, 0, 0); - Tetrahedron t = new Tetrahedron(fourCorners); - for (OrientedFace face : t) { - assertEquals(1, face.orientationOf(N)); - } - Vertex query = new Vertex(3949, 3002, 8573); - for (OrientedFace face : t) { - assertEquals(1, face.orientationOf(query)); - } - } -} diff --git a/core/src/test/java/com/hellblazer/delaunay/TetrahedralizationTest.java b/core/src/test/java/com/hellblazer/delaunay/TetrahedralizationTest.java index e43a223..0da83fc 100644 --- a/core/src/test/java/com/hellblazer/delaunay/TetrahedralizationTest.java +++ b/core/src/test/java/com/hellblazer/delaunay/TetrahedralizationTest.java @@ -25,6 +25,8 @@ import java.util.Random; import java.util.Set; +import javax.vecmath.Point3d; + import org.junit.Test; /** @@ -35,19 +37,10 @@ public class TetrahedralizationTest { - private static class OC implements StarVisitor { - int order = 0; - - @Override - public void visit(V vertex, Tetrahedron t, Vertex x, Vertex y, Vertex z) { - order++; - } - } - @Test public void testCubic() { Tetrahedralization T = new Tetrahedralization(new Random(0)); - for (Vertex v : Examples.getCubicCrystalStructure()) { + for (Point3d v : Examples.getCubicCrystalStructure()) { T.insert(v); } @@ -57,27 +50,27 @@ public void testCubic() { public void testDelete() { Tetrahedralization T = new Tetrahedralization(new Random(666)); - Vertex N = new Vertex(100, 100, 100); + Point3d N = new Point3d(100, 100, 100); T.insert(N); - Vertex O = new Vertex(5000, -1003, 101); - T.insert(O); - T.delete(N); + Point3d O = new Point3d(5000, -1003, 101); + var v = T.insert(O); + T.delete(v); assertEquals(1, T.getTetrahedrons().size()); } @Test public void testFlip4to1() { Tetrahedralization T = new Tetrahedralization(new Random(0)); - Vertex N = new Vertex(100, 100, 100); - T.insert(N); - T.flip4to1(N); + Point3d N = new Point3d(100, 100, 100); + var v = T.insert(N); + T.flip4to1(v); assertEquals(1, T.getTetrahedrons().size()); } @Test public void testGrid() { Tetrahedralization T = new Tetrahedralization(new Random(0)); - for (Vertex v : Examples.getGrid()) { + for (Point3d v : Examples.getGrid()) { T.insert(v); } @@ -88,11 +81,11 @@ public void testGrid() { @Test public void testLargeRandom() { Random random = new Random(666); - Vertex ourPoints[] = getRandomPoints(random, 60000, 100.0D, false); + Point3d ourPoints[] = getRandomPoints(random, 60000, 100.0D, false); Tetrahedralization T = new Tetrahedralization(random); - for (Vertex v : ourPoints) { + for (var v : ourPoints) { T.insert(v); } @@ -100,39 +93,14 @@ public void testLargeRandom() { assertEquals(403094, L.size()); } - /** - * Verify that the order of a vertex in a Tetrahedralization is correctly - * maintained. - */ - @Test - public void testOrderMaintenance() throws Exception { - verifyOrder(Examples.getWorstCase()); - verifyOrder(Examples.getCubicCrystalStructure()); - verifyOrder(Examples.getGrid()); - Random random = new Random(666); - verifyOrder(getRandomPoints(random, 600, 1.0D, false)); - } - @Test public void testWorstCase() { Tetrahedralization T = new Tetrahedralization(new Random(0)); - for (Vertex v : Examples.getWorstCase()) { + for (var v : Examples.getWorstCase()) { T.insert(v); } Set L = T.getTetrahedrons(); assertEquals(610, L.size()); } - - private void verifyOrder(Vertex[] vertices) { - Tetrahedralization T = new Tetrahedralization(new Random(0)); - for (Vertex v : vertices) { - T.insert(v); - } - for (Vertex v : vertices) { - OC oc = new OC(); - v.getAdjacent().visitStar(v, oc); - assertEquals(oc.order, v.getOrder()); - } - } } diff --git a/core/src/test/java/com/hellblazer/delaunay/VertexTest.java b/core/src/test/java/com/hellblazer/delaunay/VertexTest.java index 0448061..cc6417f 100644 --- a/core/src/test/java/com/hellblazer/delaunay/VertexTest.java +++ b/core/src/test/java/com/hellblazer/delaunay/VertexTest.java @@ -19,8 +19,14 @@ package com.hellblazer.delaunay; +import static com.hellblazer.delaunay.Vertex.getRandomPoints; +import static junit.framework.Assert.assertEquals; + import java.util.ArrayList; import java.util.List; +import java.util.Random; + +import javax.vecmath.Point3d; import org.junit.Test; @@ -31,6 +37,28 @@ */ public class VertexTest { + @Test + public void intersect() { + Tetrahedralization T = new Tetrahedralization(new Random(0)); + Vertex vertex = null; + for (Point3d v : Examples.getGrid()) { + vertex = T.insert(v); + } + + var origin = T.getUniverse()[0]; + + } + + @Test + public void testDeterminant() { + var a = new Vertex(7, 8, 4); + var b = new Point3d(8, 4, 6); + var c = new Point3d(2, 1, 3); + + final var det = a.determinant(b, c); + assertEquals(-54, det, 0.1); + } + @Test public void testFlip4to1() { Tetrahedralization tetrahedralization = new Tetrahedralization(); @@ -42,7 +70,54 @@ public void testFlip4to1() { U.flip1to4(N, unlinkedFacets); tetrahedralization.flip4to1(N); + } + @Test + public void testMaxStep() { + Random random = new Random(666); + Point3d ourPoints[] = getRandomPoints(random, 600, 10000.0D, false); + + Tetrahedralization T = new Tetrahedralization(random); + + for (var v : ourPoints) { + T.insert(v); + } + Point3d N = new Point3d(10, -10, 1); + + for (var v : T.getVertices()) { + v.maxStep(N); +// System.out.println(step); + } + } + + @Test + public void testOrientation() { + Vertex[] fourCorners = Tetrahedralization.getFourCorners(); + assertEquals(1, fourCorners[3].orientation(fourCorners[0], fourCorners[1], fourCorners[2])); + assertEquals(-1, fourCorners[3].orientation(fourCorners[1], fourCorners[0], fourCorners[2])); + assertEquals(0, new Vertex(100, 100, 0).orientation(new Vertex(1000, 100000, 0), new Vertex(0, -1456, 0), + new Vertex(-2567, 0, 0))); + assertEquals(1, fourCorners[0].orientation(fourCorners[2], fourCorners[1], fourCorners[3])); + + assertEquals(1, fourCorners[1].orientation(fourCorners[3], fourCorners[0], fourCorners[2])); + + assertEquals(1, fourCorners[2].orientation(fourCorners[0], fourCorners[3], fourCorners[1])); + + assertEquals(1, fourCorners[3].orientation(fourCorners[1], fourCorners[2], fourCorners[0])); + } + + @Test + public void testOrientation2() { + Vertex[] fourCorners = Tetrahedralization.getFourCorners(); + Vertex N = new Vertex(0, 0, 0); + Tetrahedron t = new Tetrahedron(fourCorners); + for (OrientedFace face : t) { + assertEquals(1, face.orientationOf(N)); + } + Vertex query = new Vertex(3949, 3002, 8573); + for (OrientedFace face : t) { + assertEquals(1, face.orientationOf(query)); + } } } diff --git a/core/src/test/java/com/hellblazer/delaunay/sturm/RootIsolatorTest.java b/core/src/test/java/com/hellblazer/delaunay/sturm/RootIsolatorTest.java new file mode 100644 index 0000000..71628e7 --- /dev/null +++ b/core/src/test/java/com/hellblazer/delaunay/sturm/RootIsolatorTest.java @@ -0,0 +1,48 @@ +package com.hellblazer.delaunay.sturm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; + +public class RootIsolatorTest { + + private static final double epsilon = 0.00001; + + private static boolean validateDoubleArrays(double[] input, double... expected) { + for (int i = 0; i < input.length; i++) { + assertEquals(input[i], expected[i], epsilon); + } + return true; + } + + @Test + public void testRootFinding() { + Polynomial p = new Polynomial(1, -2.9, 3.2, -1.66, 0.3984, -0.03456); + assertEquals(0.6, SturmRootIsolator.findRootDN(p, 0.42, 0.79, 100), 0.01); + assertEquals(0.9, SturmRootIsolator.findRootDN(p, 0.82, 0.98, 100), 0.01); + } + + @Test + public void testSturmIsolation() { + // Roots are found in [k,b) + // 5 roots are between 0 and 1 + Polynomial[] p = SturmRootIsolator.sturmSequence(1, -2.9, 3.2, -1.66, 0.3984, -0.03456); + List intervals = SturmRootIsolator.findIntervals(p); + + for (Interval v : intervals) { + assertTrue(v.contains(0.2) || v.contains(0.4) || v.contains(0.6) || v.contains(0.8) || v.contains(0.9)); + } + } + + @Test + public void testSturmSequenceIsolation() { + Polynomial[] sequence = SturmRootIsolator.sturmSequence(1, -3, 3.4, -1.8, 0.4384, -0.0384); + validateDoubleArrays(sequence[2].coeff, 2d / 25, -18d / 125, 254d / 3125, -222d / 15625); + validateDoubleArrays(sequence[3].coeff, 7d / 25, -42d / 125, 59d / 625); + validateDoubleArrays(sequence[4].coeff, 72d / 21875, -216d / 109375); + validateDoubleArrays(sequence[5].coeff, 4d / 625); + } +} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/Constants.java b/gui/src/main/java/com/hellblazer/delaunay/gui/Constants.java deleted file mode 100644 index 80e6ca9..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/Constants.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2016 Chiral Behaviors, LLC, all rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hellblazer.delaunay.gui; - -/** - * @author halhildebrand - * - */ -public class Constants { - - public static final float HALF_PI = (float) (Math.PI / 2.0); - public static float PHI = (float) ((1.0 + Math.sqrt(5.0)) / 2.0); - public static float PHI_CUBED = PHI * PHI * PHI; - public static float PHI_SQUARED = PHI * PHI; - public static final float QUARTER_PI = (float) (Math.PI / 4.0); - public static final float ROOT_2 = (float) Math.sqrt(2.0); - public static final float ROOT_2_DIV_2 = (float) (ROOT_2 / 2.0); - public static final float THREE_QUARTERS_PI = (float) (Math.PI * .75); - public static final float TWO_PI = (float) (2 * Math.PI); - -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/CubicGrid.java b/gui/src/main/java/com/hellblazer/delaunay/gui/CubicGrid.java deleted file mode 100644 index 31d2b49..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/CubicGrid.java +++ /dev/null @@ -1,268 +0,0 @@ -/** - * Copyright (c) 2016 Chiral Behaviors, LLC, all rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hellblazer.delaunay.gui; - -import static com.hellblazer.delaunay.gui.Colors.blueMaterial; -import static com.hellblazer.delaunay.gui.Colors.greenMaterial; -import static com.hellblazer.delaunay.gui.Colors.redMaterial; - -import java.util.function.BiFunction; -import java.util.function.Function; - -import javax.vecmath.Vector3d; - -import javafx.geometry.Point3D; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.paint.Material; -import javafx.scene.shape.Sphere; -import javafx.scene.transform.Transform; -import javafx.scene.transform.Translate; -import javafx.util.Pair; -import mesh.Line; -import mesh.polyhedra.plato.Cube; - -/** - * @author halhildebrand - * - */ -public class CubicGrid { - - public static enum Neighborhood { - EIGHT, SIX - } - - public static Point3D xAxis(Cube cube) { - Vector3d vector = cube.getFaces().get(0).centroid(); - return new Point3D(vector.x, vector.y, vector.z); - } - - public static Point3D yAxis(Cube cube) { - Vector3d vector = cube.getFaces().get(1).centroid(); - return new Point3D(vector.x, vector.y, vector.z); - } - - public static Point3D zAxis(Cube cube) { - Vector3d vector = cube.getFaces().get(2).centroid(); - return new Point3D(vector.x, vector.y, vector.z); - } - - private final double intervalX; - private final double intervalY; - private final double intervalZ; - private final Neighborhood neighborhood; - private Point3D origin; - private final Point3D xAxis; - private final Pair xExtent; - private final Point3D yAxis; - private final Pair yExtent; - private final Point3D zAxis; - private final Pair zExtent; - - public CubicGrid(Neighborhood neighborhood) { - this(neighborhood, new Point3D(0, 0, 0), new Pair<>(5, 5), new Point3D(1, 0, 0), 1, new Pair<>(5, 5), - new Point3D(0, 1, 0), 1, new Pair<>(5, 5), new Point3D(0, 0, 1), 1); - } - - public CubicGrid(Neighborhood neighborhood, Cube cube, int extent) { - this(neighborhood, cube, new Pair<>(extent, extent), new Pair<>(extent, extent), new Pair<>(extent, extent)); - } - - public CubicGrid(Neighborhood neighborhood, Cube cube, Pair xExtent, - Pair yExtent, Pair zExtent) { - this(neighborhood, new Point3D(0, 0, 0), xExtent, xAxis(cube), cube.getEdgeLength(), yExtent, yAxis(cube), - cube.getEdgeLength(), zExtent, zAxis(cube), cube.getEdgeLength()); - } - - public CubicGrid(Neighborhood neighborhood, Point3D origin, Pair xExtent, Point3D xAxis, - double intervalX, Pair yExtent, Point3D yAxis, double intervalY, - Pair zExtent, Point3D zAxis, double intervalZ) { - this.origin = origin; - this.neighborhood = neighborhood; - this.xExtent = xExtent; - this.xAxis = xAxis.subtract(origin).normalize(); - this.intervalX = intervalX; - this.yExtent = yExtent; - this.yAxis = yAxis.subtract(origin).normalize(); - this.intervalY = intervalY; - this.zExtent = zExtent; - this.zAxis = zAxis.subtract(origin).normalize(); - this.intervalZ = intervalZ; - } - - public Group construct(Material xaxis, Material yaxis, Material zaxis) { - Group grid = new Group(); - Point3D pos; - Point3D neg; - double bodyOffset = neighborhood == Neighborhood.SIX ? 0.5 : 0; - - final Point3D deltaX = xAxis.multiply(intervalX); - final Point3D deltaY = yAxis.multiply(intervalY); - final Point3D deltaZ = zAxis.multiply(intervalZ); - - Point3D corner; - corner = deltaY.multiply(yExtent.getKey() + bodyOffset).add(deltaZ.multiply(zExtent.getKey() + bodyOffset)); - neg = xAxis.multiply(-intervalX * (xExtent.getKey() + bodyOffset)).subtract(corner); - pos = xAxis.multiply(intervalX * (xExtent.getValue() + bodyOffset)).subtract(corner); - - construct(grid, neg, pos, yExtent.getKey() + yExtent.getValue(), zExtent.getKey() + zExtent.getValue(), xaxis, - (i, p) -> p.add(deltaY.multiply(i)), p -> p.add(deltaZ)); - - corner = deltaX.multiply(xExtent.getKey() + bodyOffset).add(deltaZ.multiply(zExtent.getKey() + bodyOffset)); - neg = yAxis.multiply(-intervalY * (yExtent.getKey() + bodyOffset)).subtract(corner); - pos = yAxis.multiply(intervalY * (yExtent.getValue() + bodyOffset)).subtract(corner); - - construct(grid, neg, pos, xExtent.getKey() + xExtent.getValue(), zExtent.getKey() + zExtent.getValue(), yaxis, - (i, p) -> p.add(deltaX.multiply(i)), p -> p.add(deltaZ)); - - corner = deltaX.multiply(xExtent.getKey() + bodyOffset).add(deltaY.multiply(yExtent.getKey() + bodyOffset)); - neg = zAxis.multiply(-intervalZ * (zExtent.getKey() + bodyOffset)).subtract(corner); - pos = zAxis.multiply(intervalZ * (zExtent.getValue() + bodyOffset)).subtract(corner); - - construct(grid, neg, pos, xExtent.getKey() + xExtent.getValue(), yExtent.getKey() + yExtent.getValue(), zaxis, - (i, p) -> p.add(deltaX.multiply(i)), p -> p.add(deltaY)); - - addAxes(grid); - return grid; - } - - public double getIntervalX() { - return intervalX; - } - - public double getIntervalY() { - return intervalY; - } - - public double getIntervalZ() { - return intervalZ; - } - - public Point3D getOrigin() { - return origin; - } - - public Point3D getxAxis() { - return xAxis; - } - - public Pair getxExtent() { - return xExtent; - } - - public Point3D getyAxis() { - return yAxis; - } - - public Pair getyExtent() { - return yExtent; - } - - public Point3D getzAxis() { - return zAxis; - } - - public Pair getzExtent() { - return zExtent; - } - - public void postition(double i, double j, double k, Node node) { - Point3D vector = xAxis.multiply(i * intervalX) - .add(yAxis.multiply(j * intervalY)) - .add(zAxis.multiply(k * intervalZ)); - node.getTransforms().add(new Translate(vector.getX(), vector.getY(), vector.getZ())); - } - - public Transform postitionTransform(double i, double j, double k) { - Point3D vector = xAxis.multiply(i * intervalX) - .add(yAxis.multiply(j * intervalY)) - .add(zAxis.multiply(k * intervalZ)); - return new Translate(vector.getX(), vector.getY(), vector.getZ()); - } - - private void addAxes(Group grid) { - Point3D xPositive = xAxis.multiply(intervalX * xExtent.getKey()); - Line axis = new Line(0.025, xAxis.multiply(-intervalX * xExtent.getKey()), xPositive); - axis.setMaterial(redMaterial); - grid.getChildren().addAll(axis); - - Sphere sphere = new Sphere(); - sphere.setMaterial(redMaterial); - sphere.setRadius(0.25); - sphere.setTranslateX(xPositive.getX()); - sphere.setTranslateY(xPositive.getY()); - sphere.setTranslateZ(xPositive.getZ()); - grid.getChildren().add(sphere); - - Point3D yPositive = yAxis.multiply(intervalY * yExtent.getKey()); - axis = new Line(0.025, yAxis.multiply(-intervalY * yExtent.getKey()), yPositive); - axis.setMaterial(blueMaterial); - grid.getChildren().addAll(axis); - sphere = new Sphere(); - sphere.setMaterial(blueMaterial); - sphere.setRadius(0.25); - sphere.setTranslateX(yPositive.getX()); - sphere.setTranslateY(yPositive.getY()); - sphere.setTranslateZ(yPositive.getZ()); - grid.getChildren().add(sphere); - - Point3D zPositive = zAxis.multiply(intervalZ * zExtent.getKey()); - axis = new Line(0.025, zAxis.multiply(-intervalZ * zExtent.getKey()), zPositive); - axis.setMaterial(greenMaterial); - grid.getChildren().addAll(axis); - sphere = new Sphere(); - sphere.setMaterial(greenMaterial); - sphere.setRadius(0.25); - sphere.setTranslateX(zPositive.getX()); - sphere.setTranslateY(zPositive.getY()); - sphere.setTranslateZ(zPositive.getZ()); - grid.getChildren().add(sphere); - } - - private void construct(Group grid, Point3D neg, Point3D pos, Integer a, Integer b, Material material, - BiFunction advanceA, Function advanceB) { - a = neighborhood == Neighborhood.SIX ? a + 1 : a; - b = neighborhood == Neighborhood.SIX ? b + 1 : b; - Point3D start = neg; - Point3D end = pos; - Line axis; - axis = new Line(0.015, start, end); - axis.setMaterial(material); - grid.getChildren().addAll(axis); - for (int x = 0; x <= a; x++) { - start = advanceA.apply(x, neg); - end = advanceA.apply(x, pos); - axis = new Line(0.015, start, end); - axis.setMaterial(material); - grid.getChildren().addAll(axis); - for (int z = 0; z < b; z++) { - start = advanceB.apply(start); - end = advanceB.apply(end); - axis = new Line(0.015, start, end); - axis.setMaterial(material); - grid.getChildren().addAll(axis); - } - } - if (neighborhood == Neighborhood.SIX) { - start = advanceA.apply(a, neg); - end = advanceA.apply(a, pos); - axis = new Line(0.015, start, end); - axis.setMaterial(material); - grid.getChildren().addAll(axis); - } - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/Inspector.java b/gui/src/main/java/com/hellblazer/delaunay/gui/Inspector.java deleted file mode 100644 index b27265d..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/Inspector.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.hellblazer.delaunay.gui; - -import java.util.Random; - -import com.hellblazer.delaunay.Tetrahedralization; -import com.hellblazer.delaunay.Vertex; -import com.javafx.experiments.jfx3dviewer.Jfx3dViewerApp; - -import javafx.scene.Group; - -/** - * - * @author Hal Hildebrand - * - */ - -public class Inspector extends Jfx3dViewerApp { - public static class Launcher { - - public static void main(String[] argv) { - Inspector.main(argv); - } - } - - public static void main(String args[]) { - launch(args); - } - - private TetrahedralizationView view; - - public Inspector() { - - } - - public Inspector(Tetrahedralization vd) { - view = new TetrahedralizationView(vd); - } - - @Override - protected void initializeContentModel() { - final var random = new Random(666); - final var tet = new Tetrahedralization(random); - Vertex ourPoints[] = Vertex.getRandomPoints(random, 120, 5.0D, true); - for (Vertex v : ourPoints) { - tet.insert(v); - } - view = new TetrahedralizationView(tet); - view.update(true, false, true); - - var content = getContentModel(); - var group = new Group(); - -// group.getChildren().add(new CubicGrid(Neighborhood.EIGHT, PhiCoordinates.Cubes[3], 1).construct(blackMaterial, blackMaterial, blackMaterial)); - group.getChildren().add(view); - - content.setContent(group); - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/LinkInspector.java b/gui/src/main/java/com/hellblazer/delaunay/gui/LinkInspector.java deleted file mode 100644 index baeb11a..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/LinkInspector.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.hellblazer.delaunay.gui; - -import static com.hellblazer.delaunay.gui.Colors.blackMaterial; - -import java.util.Random; - -import com.hellblazer.delaunay.Examples; -import com.hellblazer.delaunay.Tetrahedralization; -import com.hellblazer.delaunay.Vertex; -import com.hellblazer.delaunay.gui.CubicGrid.Neighborhood; -import com.javafx.experiments.jfx3dviewer.Jfx3dViewerApp; - -import javafx.scene.Group; - -public class LinkInspector extends Jfx3dViewerApp { - public static class Launcher { - - public static void main(String[] argv) { - LinkInspector.main(argv); - } - } - - public static void main(String[] argv) { - launch(argv); - } - - private LinkView view; - - @Override - protected void initializeContentModel() { - final Tetrahedralization tet = new Tetrahedralization(new Random(666)); - Vertex[] vertices = Examples.getCubicCrystalStructure(); - for (Vertex v : vertices) { - tet.insert(v); - } - Vertex v = vertices[13]; - view = new LinkView(v, tet.getEars(v), tet.getVoronoiRegion(v)); - - var content = getContentModel(); - var group = new Group(); - - var grid = new CubicGrid(Neighborhood.EIGHT, PhiCoordinates.Cubes[3], 1); - group.getChildren().add(grid.construct(blackMaterial, blackMaterial, blackMaterial)); - group.getChildren().add(view); - - content.setContent(group); - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/LinkView.java b/gui/src/main/java/com/hellblazer/delaunay/gui/LinkView.java deleted file mode 100644 index 4da1a18..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/LinkView.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hellblazer.delaunay.gui; - -import java.util.List; - -import javax.vecmath.Point3f; - -import com.hellblazer.delaunay.OrientedFace; -import com.hellblazer.delaunay.Vertex; - -import javafx.geometry.Point3D; - -/** - * A visualization of the link set of a vertex in a delaunay tetrahedralization. - * - * @author Hal Hildebrand - * - */ -public class LinkView extends GraphicsView { - private final List ears; - private final Vertex v; - private final List voronoiRegion; - - public LinkView(Vertex v, List ears, List voronoiRegion) { - this.v = v; - this.ears = ears; - this.voronoiRegion = voronoiRegion; - update(); - } - - public void update() { - getChildren().clear(); - for (OrientedFace ear : ears) { - Vertex[] edge = ear.getEdge(v); - Point3f[] line = new Point3f[] { edge[0].asPoint3f(), edge[1].asPoint3f() }; - newFace(line, Colors.yellowMaterial, false, this); - } - sphere(0.01F, new Point3D(v.x, v.y, v.z), Colors.violetMaterial); - render(voronoiRegion, Colors.redMaterial, true, this); - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceInspector.java b/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceInspector.java deleted file mode 100644 index dde62f0..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceInspector.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.hellblazer.delaunay.gui; - -import static com.hellblazer.delaunay.gui.Colors.blackMaterial; - -import java.util.ArrayList; -import java.util.Random; - -import com.hellblazer.delaunay.Examples; -import com.hellblazer.delaunay.Tetrahedralization; -import com.hellblazer.delaunay.Tetrahedron; -import com.hellblazer.delaunay.V; -import com.hellblazer.delaunay.Vertex; -import com.hellblazer.delaunay.gui.CubicGrid.Neighborhood; -import com.javafx.experiments.jfx3dviewer.Jfx3dViewerApp; - -import javafx.scene.Group; - -public class OrientedFaceInspector extends Jfx3dViewerApp { - public static class Launcher { - - public static void main(String[] argv) { - OrientedFaceInspector.main(argv); - } - } - - public static void main(String[] argv) { - launch(argv); - } - - private OrientedFaceView view; - - @Override - protected void initializeContentModel() { - final Tetrahedralization tet = new Tetrahedralization(new Random(666)); - for (Vertex v : Examples.getCubicCrystalStructure()) { - tet.insert(v); - } - ArrayList tets = new ArrayList<>(tet.getTetrahedrons()); - view = new OrientedFaceView(tets.get(2).getFace(V.C)); - - var content = getContentModel(); - var group = new Group(); - - var grid = new CubicGrid(Neighborhood.EIGHT, PhiCoordinates.Cubes[3], 1); - group.getChildren().add(grid.construct(blackMaterial, blackMaterial, blackMaterial)); - group.getChildren().add(view); - - content.setContent(group); - - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceView.java b/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceView.java deleted file mode 100644 index 383b6b3..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/OrientedFaceView.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (C) 2008 Hal Hildebrand. All rights reserved. - * - * This file is part of the 3D Incremental Voronoi GUI - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.hellblazer.delaunay.gui; - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.Point3f; - -import com.hellblazer.delaunay.OrientedFace; -import com.hellblazer.delaunay.Vertex; - -import javafx.geometry.Point3D; - -/** - * A visualization of an oriented face of a tetrahedron in a delaunay - * tetrahedralization. - * - * @author Hal Hildebrand - * - */ -public class OrientedFaceView extends GraphicsView { - private Point3f adjacent; - private List adjacentFaces = new ArrayList<>(); - private final OrientedFace face; - private Point3f incident; - private List incidentFaces = new ArrayList<>(); - private Point3f[] myFace = new Point3f[3]; - - public OrientedFaceView(OrientedFace face) { - super(); - this.face = face; - update(); - } - - public void update() { - updateDiagram(); - - for (Point3f p : myFace) { - getChildren().add(sphere(0.01F, new Point3D(p.x, p.y, p.z), Colors.blueMaterial)); - } - getChildren().add(sphere(0.01F, new Point3D(incident.x, incident.y, incident.z), Colors.cyanMaterial)); - if (adjacent != null) { - getChildren().add(sphere(0.01F, new Point3D(adjacent.x, adjacent.y, adjacent.z), Colors.redMaterial)); - render(adjacentFaces, Colors.yellowMaterial, false, this); - } - render(incidentFaces, Colors.purpleMaterial, false, this); - } - - private void updateDiagram() { - int i = 0; - for (Vertex v : face) { - myFace[i++] = v.asPoint3f(); - } - incidentFaces.clear(); - adjacentFaces.clear(); - incident = face.getIncidentVertex().asPoint3f(); - face.getIncident().addFacesCoordinates(incidentFaces); - if (face.hasAdjacent()) { - adjacent = face.getAdjacentVertex().asPoint3f(); - face.getAdjacent().addFacesCoordinates(adjacentFaces); - } - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/PhiCoordinates.java b/gui/src/main/java/com/hellblazer/delaunay/gui/PhiCoordinates.java deleted file mode 100644 index eceec9f..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/PhiCoordinates.java +++ /dev/null @@ -1,287 +0,0 @@ -/** - * Copyright (c) 2016 Chiral Behaviors, LLC, all rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hellblazer.delaunay.gui; - -import static com.hellblazer.delaunay.gui.Constants.PHI; -import static com.hellblazer.delaunay.gui.Constants.PHI_CUBED; -import static com.hellblazer.delaunay.gui.Constants.PHI_SQUARED; - -import javax.vecmath.Vector3d; - -import mesh.polyhedra.plato.Cube; -import mesh.polyhedra.plato.Dodecahedron; -import mesh.polyhedra.plato.Icosahedron; -import mesh.polyhedra.plato.Octahedron; -import mesh.polyhedra.plato.Tetrahedron; - -/** - * @author halhildebrand - * - * Coordinates for all the polyhedra in the 120 face polyhedron, in phi - * coordinates. - * - * Originally from Richard Gray - * (http://www.rwgrayprojects.com/Lynn/NCH/coordinates.html) - * - */ -public final class PhiCoordinates { - - public static final Cube[] Cubes; - public static final Dodecahedron Dodecahedron; - - public static final Icosahedron Icosahedron; - - public static boolean[] JITTERBUG_INVERSES = new boolean[] { false, false, false, false, true, true, true, true }; - - public static Octahedron[] Octahedrons; - - public static final Tetrahedron[] Tetrahedrons; - - // 1 icosahedron - private static int[] IcosaVertices = { 2, 6, 12, 17, 27, 31, 33, 37, 46, 51, 54, 58 }; - - private static final float[] MeshPoints; - - // 5 differnet octahedra - private static int[][] OctahedronVertices = { { 7, 10, 22, 43, 49, 55 }, { 9, 21, 14, 53, 42, 57 }, - { 25, 3, 15, 44, 59, 40 }, { 19, 5, 24, 39, 61, 48 }, - - { 26, 1, 35, 29, 62, 32 } }; - - @SuppressWarnings("unused") - private static int[] P120EdgeMap = { 1, 2, 1, 4, 1, 6, 1, 8, 2, 3, 2, 4, 2, 8, 2, 9, 2, 10, 2, 11, 2, 18, 2, 19, 2, - 20, 3, 4, 3, 11, 3, 12, 4, 5, 4, 6, 4, 12, 5, 6, 5, 12, 5, 13, 6, 7, 6, 8, 6, - 13, 6, 14, 6, 15, 6, 16, 6, 23, 7, 8, 7, 16, 7, 17, 8, 9, 8, 17, 9, 17, 9, 18, - 10, 11, 10, 20, 10, 27, 11, 12, 11, 21, 11, 27, 12, 13, 12, 21, 12, 28, 12, 29, - 12, 22, 12, 30, 13, 14, 13, 22, 13, 31, 14, 23, 14, 31, 15, 16, 15, 23, 15, 33, - 16, 17, 16, 24, 16, 33, 17, 18, 17, 24, 17, 25, 17, 34, 17, 35, 17, 36, 18, 19, - 18, 25, 18, 37, 19, 20, 19, 37, 20, 26, 20, 27, 20, 37, 21, 27, 21, 28, 22, 30, - 22, 31, 23, 31, 23, 32, 23, 33, 24, 33, 24, 34, 25, 36, 25, 37, 26, 27, 26, 37, - 26, 38, 27, 28, 27, 38, 27, 39, 27, 44, 27, 45, 28, 29, 28, 39, 28, 46, 29, 30, - 29, 46, 30, 31, 30, 40, 30, 46, 31, 32, 31, 40, 31, 41, 31, 47, 31, 48, 32, 33, - 32, 41, 33, 34, 33, 41, 33, 42, 33, 49, 33, 50, 34, 35, 34, 42, 34, 51, 35, 36, - 35, 51, 36, 37, 36, 43, 36, 51, 37, 38, 37, 43, 37, 52, 37, 53, 38, 44, 38, 53, - 38, 54, 39, 45, 39, 46, 40, 46, 40, 47, 41, 48, 41, 49, 41, 58, 42, 50, 42, 51, - 43, 51, 43, 52, 44, 45, 44, 54, 45, 55, 45, 46, 45, 54, 46, 47, 46, 55, 46, 56, - 46, 57, 47, 48, 47, 57, 47, 58, 48, 58, 49, 50, 49, 58, 50, 51, 50, 58, 50, 59, - 51, 52, 51, 59, 51, 60, 51, 61, 52, 53, 52, 61, 52, 54, 53, 54, 54, 55, 54, 56, - 54, 60, 54, 61, 54, 62, 55, 56, 56, 57, 56, 58, 56, 62, 57, 58, 58, 59, 58, 60, - 58, 62, 59, 60, 60, 61, 60, 62, }; - - @SuppressWarnings("unused") - private static int[] P120FaceMap = { 1, 2, 4, 2, 3, 4, 2, 20, 10, 2, 10, 11, 2, 11, 3, 3, 11, 12, 3, 12, 4, 20, 26, - 27, 20, 27, 10, 10, 27, 11, 11, 27, 21, 11, 21, 12, 21, 27, 28, 12, 21, 28, 12, - 28, 29, 1, 4, 6, 4, 12, 5, 4, 5, 6, 5, 12, 13, 5, 13, 6, 6, 13, 14, 6, 14, 23, - 12, 29, 30, 12, 30, 22, 12, 22, 13, 13, 22, 31, 22, 30, 31, 13, 31, 14, 14, 31, - 23, 23, 31, 32, 1, 6, 8, 6, 23, 15, 6, 15, 16, 6, 16, 7, 6, 7, 8, 8, 7, 17, 7, - 16, 17, 23, 32, 33, 15, 23, 33, 16, 15, 33, 24, 16, 33, 34, 24, 33, 17, 16, 24, - 17, 24, 34, 17, 34, 35, 1, 8, 2, 8, 17, 9, 8, 9, 2, 9, 17, 18, 9, 18, 2, 2, 18, - 19, 2, 19, 20, 17, 35, 36, 17, 36, 25, 17, 25, 18, 18, 25, 37, 25, 36, 37, 19, - 18, 37, 20, 19, 37, 20, 37, 26, 27, 26, 38, 27, 38, 44, 27, 44, 45, 27, 45, 39, - 27, 39, 28, 28, 39, 46, 28, 46, 29, 39, 45, 46, 38, 54, 44, 55, 45, 54, 45, 44, - 54, 45, 55, 46, 46, 55, 56, 55, 54, 56, 56, 54, 62, 30, 29, 46, 30, 46, 40, 31, - 30, 40, 40, 46, 47, 31, 40, 47, 31, 47, 48, 31, 48, 41, 31, 41, 32, 46, 56, 57, - 47, 46, 57, 47, 57, 58, 48, 47, 58, 41, 48, 58, 57, 56, 58, 58, 56, 62, 33, 32, - 41, 33, 41, 49, 33, 49, 50, 33, 50, 42, 33, 42, 34, 34, 42, 51, 42, 50, 51, 35, - 34, 51, 49, 41, 58, 50, 49, 58, 50, 58, 59, 51, 50, 59, 51, 59, 60, 59, 58, 60, - 60, 58, 62, 36, 35, 51, 36, 51, 43, 37, 36, 43, 43, 51, 52, 37, 43, 52, 37, 52, - 53, 37, 53, 38, 37, 38, 26, 51, 60, 61, 52, 51, 61, 52, 61, 54, 53, 52, 54, 38, - 53, 54, 54, 61, 60, 54, 60, 62 }; - - // 1 120 Polyhedron - @SuppressWarnings("unused") - private static int[] P120Vertices = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62 }; - - private static Vector3d[] POLY_120_VECTORS = { new Vector3d(0.0, 0.0, 0.0), // 00 center of volume - - new Vector3d(0.0, 0.0, 2.0 * PHI_SQUARED), // 01 - - new Vector3d(PHI_SQUARED, 0.0, PHI_CUBED), // 02 - new Vector3d(PHI, PHI_SQUARED, PHI_CUBED), // 03 - new Vector3d(0.0, PHI, PHI_CUBED), // 04 - new Vector3d(-PHI, PHI_SQUARED, PHI_CUBED), // 05 - new Vector3d(-PHI_SQUARED, 0.0, PHI_CUBED), // 06 - new Vector3d(-PHI, -PHI_SQUARED, PHI_CUBED), // 07 - new Vector3d(0.0, -PHI, PHI_CUBED), // 08 - new Vector3d(PHI, -PHI_SQUARED, PHI_CUBED), // 09 - - new Vector3d(PHI_CUBED, PHI, PHI_SQUARED), // 10 - new Vector3d(PHI_SQUARED, PHI_SQUARED, PHI_SQUARED), // 11 - new Vector3d(0.0, PHI_CUBED, PHI_SQUARED), // 12 - new Vector3d(-PHI_SQUARED, PHI_SQUARED, PHI_SQUARED), // 13 - new Vector3d(-PHI_CUBED, PHI, PHI_SQUARED), // 14 - new Vector3d(-PHI_CUBED, -PHI, PHI_SQUARED), // 15 - new Vector3d(-PHI_SQUARED, -PHI_SQUARED, PHI_SQUARED), // 16 - new Vector3d(0.0, -PHI_CUBED, PHI_SQUARED), // 17 - new Vector3d(PHI_SQUARED, -PHI_SQUARED, PHI_SQUARED), // 18 - new Vector3d(PHI_CUBED, -PHI, PHI_SQUARED), // 19 - - new Vector3d(PHI_CUBED, 0.0, PHI), // 20 - new Vector3d(PHI_SQUARED, PHI_CUBED, PHI), // 21 - new Vector3d(-PHI_SQUARED, PHI_CUBED, PHI), // 22 - new Vector3d(-PHI_CUBED, 0.0, PHI), // 23 - new Vector3d(-PHI_SQUARED, -PHI_CUBED, PHI), // 24 - new Vector3d(PHI_SQUARED, -PHI_CUBED, PHI), // 25 - - new Vector3d(2.0 * PHI_SQUARED, 0.0, 0.0), // 26 - new Vector3d(PHI_CUBED, PHI_SQUARED, 0.0), // 27 - new Vector3d(PHI, PHI_CUBED, 0.0), // 28 - new Vector3d(0.0, 2.0 * PHI_SQUARED, 0.0), // 29 - new Vector3d(-PHI, PHI_CUBED, 0.0), // 30 - new Vector3d(-PHI_CUBED, PHI_SQUARED, 0.0), // 31 - new Vector3d(-2.0 * PHI_SQUARED, 0.0, 0.0), // 32 - new Vector3d(-PHI_CUBED, -PHI_SQUARED, 0.0), // 33 - new Vector3d(-PHI, -PHI_CUBED, 0.0), // 34 - new Vector3d(0.0, -2.0 * PHI_SQUARED, 0.0), // 35 - new Vector3d(PHI, -PHI_CUBED, 0.0), // 36 - new Vector3d(PHI_CUBED, -PHI_SQUARED, 0.0), // 37 - - new Vector3d(PHI_CUBED, 0.0, -PHI), // 38 - new Vector3d(PHI_SQUARED, PHI_CUBED, -PHI), // 39 - new Vector3d(-PHI_SQUARED, PHI_CUBED, -PHI), // 40 - new Vector3d(-PHI_CUBED, 0.0, -PHI), // 41 - new Vector3d(-PHI_SQUARED, -PHI_CUBED, -PHI), // 42 - new Vector3d(PHI_SQUARED, -PHI_CUBED, -PHI), // 43 - - new Vector3d(PHI_CUBED, PHI, -PHI_SQUARED), // 44 - new Vector3d(PHI_SQUARED, PHI_SQUARED, -PHI_SQUARED), // 45 - new Vector3d(0.0, PHI_CUBED, -PHI_SQUARED), // 46 - new Vector3d(-PHI_SQUARED, PHI_SQUARED, -PHI_SQUARED), // 47 - new Vector3d(-PHI_CUBED, PHI, -PHI_SQUARED), // 48 - new Vector3d(-PHI_CUBED, -PHI, -PHI_SQUARED), // 49 - new Vector3d(-PHI_SQUARED, -PHI_SQUARED, -PHI_SQUARED), // 50 - new Vector3d(0.0, -PHI_CUBED, -PHI_SQUARED), // 51 - new Vector3d(PHI_SQUARED, -PHI_SQUARED, -PHI_SQUARED), // 52 - new Vector3d(PHI_CUBED, -PHI, -PHI_SQUARED), // 53 - - new Vector3d(PHI_SQUARED, 0.0, -PHI_CUBED), // 54 - new Vector3d(PHI, PHI_SQUARED, -PHI_CUBED), // 55 - new Vector3d(0.0, PHI, -PHI_CUBED), // 56 - new Vector3d(-PHI, PHI_SQUARED, -PHI_CUBED), // 57 - new Vector3d(-PHI_SQUARED, 0.0, -PHI_CUBED), // 58 - new Vector3d(-PHI, -PHI_SQUARED, -PHI_CUBED), // 59 - new Vector3d(0.0, -PHI, -PHI_CUBED), // 60 - new Vector3d(PHI, -PHI_SQUARED, -PHI_CUBED), // 61 - - new Vector3d(0.0, 0.0, -2.0 * PHI_SQUARED) // 62 - }; - - // 1 regular dodecahedron - private static int[] RegDodecahedronVertices = { 4, 8, 11, 13, 16, 18, 20, 23, 28, 30, 34, 36, 38, 41, 45, 47, 50, - 52, 56, 60 }; - - // 5 rhombic dodecahedra - @SuppressWarnings("unused") - private static int[][] RhDodecahedronVertices = { { 4, 7, 10, 18, 22, 23, 28, 34, 38, 43, 47, 49, 55, 60 }, - { 4, 9, 14, 16, 20, 21, 30, 36, 41, 42, 45, 53, 57, 60 }, - { 3, 8, 13, 15, 20, 25, 28, 34, 40, 41, 44, 52, 56, 59 }, - { 5, 8, 11, 19, 23, 24, 30, 36, 38, 39, 48, 50, 56, 61 }, - { 1, 11, 13, 16, 18, 26, 29, 32, 35, 45, 47, 50, 52, 62 } }; - // 1 rhombic triacontahedron - @SuppressWarnings("unused") - private static int[] RhTriaVertices = { 2, 4, 6, 8, 11, 12, 13, 16, 17, 18, 20, 23, 27, 28, 30, 31, 33, 34, 36, 37, - 38, 41, 45, 46, 47, 50, 51, 52, 54, 56, 58, 60 }; - // 10 different tetrahedra - private static int[][] TetrahedronVertices = { { 47, 34, 4, 38 }, { 18, 28, 60, 23 }, - - { 30, 16, 20, 60 }, { 36, 45, 41, 4 }, - - { 28, 41, 8, 52 }, { 34, 20, 56, 13 }, - - { 45, 50, 13, 18 }, { 16, 11, 52, 47 }, - - { 56, 23, 11, 36 }, { 8, 38, 50, 30 } - - }; - - static { - MeshPoints = new float[POLY_120_VECTORS.length * 3]; - int i = 0; - for (Vector3d v : POLY_120_VECTORS) { - MeshPoints[i++] = (float) v.x; - MeshPoints[i++] = (float) v.y; - MeshPoints[i++] = (float) v.z; - } - - Cubes = cubes(); - Dodecahedron = dodecahedron(); - Icosahedron = icosahedron(); - Octahedrons = octahedrons(); - Tetrahedrons = tetrahedrons(); - } - - public static Vector3d[] pointsFrom(int[] indices) { - Vector3d[] vectors = new Vector3d[indices.length]; - int i = 0; - for (int index : indices) { - vectors[i++] = POLY_120_VECTORS[index]; - } - return vectors; - } - - private static Cube[] cubes() { - Cube[] cubes = new Cube[5]; - int j = 0; - for (int i = 0; i < TetrahedronVertices.length / 2; i++) { - int[] a = TetrahedronVertices[i * 2]; - int[] b = TetrahedronVertices[i * 2 + 1]; - int[] coordinates = new int[] { a[0], b[1], a[3], b[2], a[1], b[0], a[2], b[3] }; - cubes[j++] = new Cube(pointsFrom(coordinates)); - } - return cubes; - } - - private static Dodecahedron dodecahedron() { - return new Dodecahedron(pointsFrom(RegDodecahedronVertices)); - } - - private static Icosahedron icosahedron() { - return new Icosahedron(pointsFrom(IcosaVertices)); - } - - private static Octahedron[] octahedrons() { - Octahedron[] octahedrons = new Octahedron[OctahedronVertices.length]; - int i = 0; - for (int[] coordinates : OctahedronVertices) { - Vector3d[] vectors = pointsFrom(coordinates); - Vector3d[] normalized = new Vector3d[vectors.length]; - normalized[0] = vectors[2]; - normalized[1] = vectors[1]; - normalized[2] = vectors[3]; - normalized[3] = vectors[5]; - normalized[4] = vectors[0]; - normalized[5] = vectors[4]; - octahedrons[i++] = new Octahedron(vectors); - } - return octahedrons; - } - - private static Tetrahedron[] tetrahedrons() { - Tetrahedron[] tetrahedrons = new Tetrahedron[TetrahedronVertices.length]; - int i = 0; - for (int[] coordinates : TetrahedronVertices) { - tetrahedrons[i++] = new Tetrahedron((i & 1) == 0, pointsFrom(coordinates)); - } - return tetrahedrons; - } - - private PhiCoordinates() { - } -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/PointModel.java b/gui/src/main/java/com/hellblazer/delaunay/gui/PointModel.java deleted file mode 100644 index 233d1c5..0000000 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/PointModel.java +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright (C) 2008 Hal Hildebrand. All rights reserved. - * - * This file is part of the 3D Incremental Voronoi GUI - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.hellblazer.delaunay.gui; - -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.table.AbstractTableModel; - -import com.hellblazer.delaunay.Vertex; - -/** - * - * @author Hal Hildebrand - * - */ - -public class PointModel extends AbstractTableModel { - private static final long serialVersionUID = 1L; - private ArrayList data; - private NumberFormat numberFormatter; - - PointModel() { - data = null; - numberFormatter = new DecimalFormat("0.000"); - data = new ArrayList<>(); - } - - PointModel(List somePoints) { - data = null; - numberFormatter = new DecimalFormat("0.000"); - if (somePoints != null && somePoints.size() != 0) { - data = new ArrayList<>(somePoints.size()); - for (Vertex somePoint : somePoints) { - data.add(somePoint); - } - - } else { - data = new ArrayList<>(); - } - } - - public synchronized void clear() { - int oldNumRows = data.size(); - data.clear(); - fireTableRowsUpdated(0, oldNumRows); - } - - @Override - public synchronized int getColumnCount() { - return 3; - } - - @Override - public String getColumnName(int columnIndex) { - if (columnIndex < 0 || columnIndex > 3) { - return null; - } - switch (columnIndex) { - case 0: - return "x"; - - case 1: - return "y"; - - case 2: - return "z"; - } - return null; - } - - @Override - public synchronized int getRowCount() { - return data.size(); - } - - @Override - public synchronized Object getValueAt(int rowIndex, int columnIndex) { - if (rowIndex < 0 || rowIndex > getRowCount()) { - return null; - } - if (data != null && data.size() > 0) { - switch (columnIndex) { - case 0: - return numberFormatter.format(data.get(rowIndex).asPoint3f().x); - - case 1: - return numberFormatter.format(data.get(rowIndex).asPoint3f().y); - - case 2: - return numberFormatter.format(data.get(rowIndex).asPoint3f().z); - } - return null; - } else { - return null; - } - } - -} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/Colors.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/Colors.java similarity index 99% rename from gui/src/main/java/com/hellblazer/delaunay/gui/Colors.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/Colors.java index f999109..e68bbec 100644 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/Colors.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/Colors.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.hellblazer.delaunay.gui; +package com.hellblazer.voronoi3d.gui; import static javafx.scene.paint.Color.BLACK; import static javafx.scene.paint.Color.BLUE; diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/GraphicsView.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/GraphicsView.java similarity index 65% rename from gui/src/main/java/com/hellblazer/delaunay/gui/GraphicsView.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/GraphicsView.java index 0289478..421643b 100644 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/GraphicsView.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/GraphicsView.java @@ -1,14 +1,16 @@ -package com.hellblazer.delaunay.gui; +package com.hellblazer.voronoi3d.gui; -import java.util.Collection; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.vecmath.Point3f; +import javax.vecmath.Tuple3d; import javax.vecmath.Vector3d; import com.hellblazer.delaunay.Vertex; +import com.hellblazer.voronoi3d.gui.mesh.Face; +import com.hellblazer.voronoi3d.gui.mesh.Mesh; +import com.hellblazer.voronoi3d.gui.mesh.PolyLine; import javafx.geometry.Point3D; import javafx.scene.Group; @@ -18,27 +20,14 @@ import javafx.scene.shape.CullFace; import javafx.scene.shape.MeshView; import javafx.scene.shape.Sphere; -import mesh.Face; -import mesh.Mesh; -import mesh.PolyLine; public class GraphicsView extends Group { - public static Point3D p(Vertex v) { + public static Point3D p(Tuple3d v) { return new Point3D(v.x, v.y, v.z); } - protected static Point3f[] convertToPoint3f(List somePoints) { - Point3f tmp[] = new Point3f[somePoints.size()]; - int i = 0; - for (Vertex v : somePoints) { - tmp[i++] = v.asPoint3f(); - } - - return tmp; - } - - public void newFace(Point3f[] verts, PhongMaterial color, boolean showFace, Group group) { + public void newFace(Tuple3d[] verts, PhongMaterial color, boolean showFace, Group group) { List vertices; if (showFace) { Mesh mesh = new Mesh(); @@ -55,10 +44,11 @@ public void newFace(Point3f[] verts, PhongMaterial color, boolean showFace, Grou view.setCullFace(CullFace.BACK); view.setMaterial(color); group.getChildren().addAll(view); + } else { + vertices = Stream.of(verts).map(v -> p(v)).collect(Collectors.toList()); + vertices.add(vertices.get(0)); + group.getChildren().add(new PolyLine(vertices, 0.01, Colors.blackMaterial)); } - vertices = Stream.of(verts).map(v -> p(v)).collect(Collectors.toList()); - vertices.add(vertices.get(0)); - group.getChildren().add(new PolyLine(vertices, 0.01, Colors.blackMaterial)); } public Sphere sphere(double radius, Point3D position, Material material) { @@ -71,24 +61,24 @@ public Sphere sphere(double radius, Point3D position, Material material) { return sphere; } - protected void displaySpheres(Collection selected, double aRadius, PhongMaterial aColor, Group group) { + protected void displaySpheres(Stream selected, double aRadius, PhongMaterial aColor, Group group) { final var children = group.getChildren(); - for (Vertex v : selected) { + selected.forEach(v -> { children.add(sphere(aRadius, p(v), aColor)); - } + }); } - protected boolean isAuxillary(Point3f[] face) { + protected boolean isAuxillary(Tuple3d[] face) { return false; } - protected void render(List region, PhongMaterial color, boolean showFaces, Group group) { + protected void render(List region, PhongMaterial color, boolean showFaces, Group group) { for (var face : region) { color = render(face, color, showFaces, group); } } - protected PhongMaterial render(Point3f[] face, PhongMaterial color, boolean showFaces, Group group) { + protected PhongMaterial render(Tuple3d[] face, PhongMaterial color, boolean showFaces, Group group) { if (!isAuxillary(face)) { final var c = color.getDiffuseColor(); color = new PhongMaterial(new Color(c.getRed(), c.getGreen(), c.getBlue(), 0.1)); @@ -96,8 +86,4 @@ protected PhongMaterial render(Point3f[] face, PhongMaterial color, boolean show } return color; } - - private Point3D p(Point3f v) { - return new Point3D(v.x, v.y, v.z); - } } diff --git a/gui/src/main/java/com/hellblazer/voronoi3d/gui/TestCases.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TestCases.java new file mode 100644 index 0000000..1f15eb4 --- /dev/null +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TestCases.java @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2008 Hal Hildebrand. All rights reserved. + * + * This file is part of the 3F Incremental Voronoi GUI + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.hellblazer.voronoi3d.gui; + +import java.util.ArrayList; + +import javax.vecmath.Point3f; + +/** + * + * @author Hal Hildebrand + * + */ + +public class TestCases { + + public static Point3f[] getCubicCrystalStructure() { + ArrayList list = new ArrayList<>(); + list.add(new Point3f(-0.89999799999999996F, -0.89999200000000001F, -0.900003F)); + list.add(new Point3f(-0.90000199999999997F, -0.90000800000000003F, -6.9999999999999999E-06F)); + list.add(new Point3f(-0.89999499999999999F, -0.90000199999999997F, 0.900003F)); + list.add(new Point3f(-0.89999099999999999F, 5.0000000000000004E-06F, -0.89999099999999999F)); + list.add(new Point3f(-0.89999399999999996F, 9.9999999999999995E-07F, 5.0000000000000004E-06F)); + list.add(new Point3f(-0.90000800000000003F, 5.0000000000000004E-06F, 0.90000500000000005F)); + list.add(new Point3f(-0.89999499999999999F, 0.89999099999999999F, -0.89999600000000002F)); + list.add(new Point3f(-0.90000100000000005F, 0.90000000000000002F, -1.9999999999999999E-06F)); + list.add(new Point3f(-0.89999499999999999F, 0.90000199999999997F, 0.89999899999999999F)); + list.add(new Point3f(-6.0000000000000002E-06F, -0.89999600000000002F, -0.90000599999999997F)); + list.add(new Point3f(-6.0000000000000002E-06F, -0.900007F, -6.0000000000000002E-06F)); + list.add(new Point3f(-3.0000000000000001E-06F, -0.90000100000000005F, 0.89999600000000002F)); + list.add(new Point3f(3.9999999999999998E-06F, 0.0F, -0.89999399999999996F)); + list.add(new Point3f(-9.0000000000000002E-06F, 5.0000000000000004E-06F, 1.0000000000000001E-05F)); + list.add(new Point3f(-6.0000000000000002E-06F, -1.9999999999999999E-06F, 0.89999799999999996F)); + list.add(new Point3f(9.0000000000000002E-06F, 0.89999600000000002F, -0.90000599999999997F)); + list.add(new Point3f(1.0000000000000001E-05F, 0.90000100000000005F, 3.9999999999999998E-06F)); + list.add(new Point3f(-6.9999999999999999E-06F, 0.90000899999999995F, 0.89999600000000002F)); + list.add(new Point3f(0.89999799999999996F, -0.90000800000000003F, -0.89999600000000002F)); + list.add(new Point3f(0.90000500000000005F, -0.89999899999999999F, -1.9999999999999999E-06F)); + list.add(new Point3f(0.89999600000000002F, -0.89999099999999999F, 0.90000199999999997F)); + list.add(new Point3f(0.89999499999999999F, 9.9999999999999995E-07F, -0.89999700000000005F)); + list.add(new Point3f(0.90000500000000005F, -5.0000000000000004E-06F, -3.9999999999999998E-06F)); + list.add(new Point3f(0.89999799999999996F, -3.9999999999999998E-06F, 0.89999899999999999F)); + list.add(new Point3f(0.90000599999999997F, 0.900003F, -0.89999600000000002F)); + list.add(new Point3f(0.89999600000000002F, 0.89999899999999999F, -6.9999999999999999E-06F)); + list.add(new Point3f(0.90000400000000003F, 0.89999499999999999F, 0.900003F)); + list.add(new Point3f(-0.44999499999999998F, -0.44999099999999997F, -0.45001000000000002F)); + list.add(new Point3f(-0.45000200000000001F, -0.45000499999999999F, 0.44999499999999998F)); + list.add(new Point3f(-0.449992F, 0.44999099999999997F, -0.449992F)); + list.add(new Point3f(-0.44999499999999998F, 0.45000600000000002F, 0.44999099999999997F)); + list.add(new Point3f(0.45000099999999998F, -0.44999600000000001F, -0.44999600000000001F)); + list.add(new Point3f(0.44999800000000001F, -0.45000899999999999F, 0.44999299999999998F)); + list.add(new Point3f(0.44999400000000001F, 0.44999499999999998F, -0.45000800000000002F)); + list.add(new Point3f(0.45000800000000002F, 0.44999600000000001F, 0.45000699999999999F)); + return list.toArray(new Point3f[list.size()]); + } + + public static Point3f[] getGrid() { + ArrayList list; + list = new ArrayList<>(); + list.add(new Point3f(-0.74999800000000005F, -0.74999199999999999F, -0.75000299999999998F)); + list.add(new Point3f(-0.75000199999999995F, -0.75000800000000001F, -0.25000699999999998F)); + list.add(new Point3f(-0.74999499999999997F, -0.75000199999999995F, 0.25000299999999998F)); + list.add(new Point3f(-0.74999099999999996F, -0.74999499999999997F, 0.75000900000000004F)); + list.add(new Point3f(-0.74999400000000005F, -0.249999F, -0.74999499999999997F)); + list.add(new Point3f(-0.75000800000000001F, -0.24999499999999999F, -0.24999499999999999F)); + list.add(new Point3f(-0.74999499999999997F, -0.25000899999999998F, 0.250004F)); + list.add(new Point3f(-0.75000100000000003F, -0.25F, 0.74999800000000005F)); + list.add(new Point3f(-0.74999499999999997F, 0.250002F, -0.75000100000000003F)); + list.add(new Point3f(-0.75000599999999995F, 0.250004F, -0.25000600000000001F)); + list.add(new Point3f(-0.75000599999999995F, 0.24999299999999999F, 0.24999399999999999F)); + list.add(new Point3f(-0.75000299999999998F, 0.249999F, 0.749996F)); + list.add(new Point3f(-0.749996F, 0.75F, -0.74999400000000005F)); + list.add(new Point3f(-0.75000900000000004F, 0.75000500000000003F, -0.24998999999999999F)); + list.add(new Point3f(-0.75000599999999995F, 0.74999800000000005F, 0.249998F)); + list.add(new Point3f(-0.74999099999999996F, 0.749996F, 0.74999400000000005F)); + list.add(new Point3f(-0.24998999999999999F, -0.74999899999999997F, -0.749996F)); + list.add(new Point3f(-0.25000699999999998F, -0.74999099999999996F, -0.250004F)); + list.add(new Point3f(-0.250002F, -0.75000800000000001F, 0.250004F)); + list.add(new Point3f(-0.24999499999999999F, -0.74999899999999997F, 0.74999800000000005F)); + list.add(new Point3f(-0.250004F, -0.24999099999999999F, -0.74999800000000005F)); + list.add(new Point3f(-0.25000499999999998F, -0.249999F, -0.249997F)); + list.add(new Point3f(-0.24999499999999999F, -0.25000499999999998F, 0.249996F)); + list.add(new Point3f(-0.250002F, -0.250004F, 0.74999899999999997F)); + list.add(new Point3f(-0.24999399999999999F, 0.25000299999999998F, -0.749996F)); + list.add(new Point3f(-0.250004F, 0.249999F, -0.25000699999999998F)); + list.add(new Point3f(-0.249996F, 0.24999499999999999F, 0.25000299999999998F)); + list.add(new Point3f(-0.24999499999999999F, 0.25000899999999998F, 0.74999000000000005F)); + list.add(new Point3f(-0.250002F, 0.74999499999999997F, -0.75000500000000003F)); + list.add(new Point3f(-0.24999199999999999F, 0.74999099999999996F, -0.24999199999999999F)); + list.add(new Point3f(-0.24999499999999999F, 0.75000599999999995F, 0.24999099999999999F)); + list.add(new Point3f(-0.249999F, 0.750004F, 0.750004F)); + list.add(new Point3f(0.249998F, -0.75000900000000004F, -0.75000699999999998F)); + list.add(new Point3f(0.24999399999999999F, -0.75000500000000003F, -0.25000800000000001F)); + list.add(new Point3f(0.25000800000000001F, -0.750004F, 0.25000699999999998F)); + list.add(new Point3f(0.25000099999999997F, -0.75F, 0.75000800000000001F)); + list.add(new Point3f(0.250002F, -0.25000699999999998F, -0.75000900000000004F)); + list.add(new Point3f(0.249997F, -0.249997F, -0.24999299999999999F)); + list.add(new Point3f(0.249996F, -0.24999499999999999F, 0.25001000000000001F)); + list.add(new Point3f(0.25000800000000001F, -0.25000699999999998F, 0.75000100000000003F)); + list.add(new Point3f(0.24999499999999999F, 0.249996F, -0.749996F)); + list.add(new Point3f(0.249998F, 0.250004F, -0.24999099999999999F)); + list.add(new Point3f(0.249998F, 0.25000099999999997F, 0.25000299999999998F)); + list.add(new Point3f(0.25000099999999997F, 0.24999399999999999F, 0.74999300000000002F)); + list.add(new Point3f(0.25001000000000001F, 0.749996F, -0.75000699999999998F)); + list.add(new Point3f(0.250004F, 0.750004F, -0.25000899999999998F)); + list.add(new Point3f(0.25000800000000001F, 0.74999099999999996F, 0.249996F)); + list.add(new Point3f(0.24999299999999999F, 0.74999000000000005F, 0.75000100000000003F)); + list.add(new Point3f(0.75000299999999998F, -0.74999700000000002F, -0.75000900000000004F)); + list.add(new Point3f(0.74999899999999997F, -0.75000199999999995F, -0.24999399999999999F)); + list.add(new Point3f(0.74999700000000002F, -0.75000599999999995F, 0.249997F)); + list.add(new Point3f(0.75000900000000004F, -0.75000800000000001F, 0.75F)); + list.add(new Point3f(0.75000900000000004F, -0.24999499999999999F, -0.74999499999999997F)); + list.add(new Point3f(0.74999800000000005F, -0.25000899999999998F, -0.250002F)); + list.add(new Point3f(0.75F, -0.250004F, 0.25000699999999998F)); + list.add(new Point3f(0.749996F, -0.25F, 0.749996F)); + list.add(new Point3f(0.75000199999999995F, 0.24999199999999999F, -0.75000500000000003F)); + list.add(new Point3f(0.750004F, 0.25000899999999998F, -0.25F)); + list.add(new Point3f(0.75000500000000003F, 0.25001000000000001F, 0.250002F)); + list.add(new Point3f(0.74999800000000005F, 0.25000699999999998F, 0.75000599999999995F)); + list.add(new Point3f(0.75000599999999995F, 0.75000299999999998F, -0.75F)); + list.add(new Point3f(0.74999199999999999F, 0.74999800000000005F, -0.25000600000000001F)); + list.add(new Point3f(0.74999300000000002F, 0.74999400000000005F, 0.24998999999999999F)); + list.add(new Point3f(0.75000299999999998F, 0.75000699999999998F, 0.75000199999999995F)); + return list.toArray(new Point3f[list.size()]); + } + + public static Point3f[] getWorstCase() { + ArrayList list; + list = new ArrayList<>(); + + list.add(new Point3f(-0.36000100000000002F, 7.9999999999999996E-06F, 0.96000099999999999F)); + list.add(new Point3f(0.120003F, 0.88000900000000004F, 0.120002F)); + list.add(new Point3f(-0.30000100000000002F, 0.0F, 0.900003F)); + list.add(new Point3f(0.100004F, 0.80000899999999997F, 0.100007F)); + list.add(new Point3f(-0.240008F, 7.9999999999999996E-06F, 0.84000399999999997F)); + list.add(new Point3f(0.080005999999999994F, 0.72000699999999995F, 0.080005000000000007F)); + list.add(new Point3f(-0.180009F, 6.0000000000000002E-06F, 0.780003F)); + list.add(new Point3f(0.060006999999999998F, 0.64000500000000005F, 0.060002F)); + list.add(new Point3f(-0.120005F, 3.9999999999999998E-06F, 0.72000900000000001F)); + list.add(new Point3f(0.040003999999999998F, 0.56000300000000003F, 0.040004999999999999F)); + list.add(new Point3f(-0.060003000000000001F, 1.9999999999999999E-06F, 0.66000300000000001F)); + list.add(new Point3f(0.020004000000000001F, 0.48000100000000001F, 0.020001999999999999F)); + list.add(new Point3f(6.0000000000000002E-06F, 9.0000000000000002E-06F, 0.60000600000000004F)); + list.add(new Point3f(6.0000000000000002E-06F, 0.40000799999999997F, 9.0000000000000002E-06F)); + list.add(new Point3f(0.060000999999999999F, 6.9999999999999999E-06F, 0.54000800000000004F)); + list.add(new Point3f(-0.020003F, 0.32000600000000001F, -0.020005999999999999F)); + list.add(new Point3f(0.120007F, 5.0000000000000004E-06F, 0.48000399999999999F)); + list.add(new Point3f(-0.040003999999999998F, 0.240004F, -0.040003999999999998F)); + list.add(new Point3f(0.180008F, 3.0000000000000001E-06F, 0.42000300000000002F)); + list.add(new Point3f(-0.060000999999999999F, 0.16000200000000001F, -0.060002F)); + list.add(new Point3f(0.240007F, 9.9999999999999995E-07F, 0.36000700000000002F)); + list.add(new Point3f(-0.080004000000000006F, 0.080004000000000006F, -0.080008999999999997F)); + list.add(new Point3f(0.30000199999999999F, 1.9999999999999999E-06F, 0.30000100000000002F)); + list.add(new Point3f(-0.10000299999999999F, 3.0000000000000001E-06F, -0.10000199999999999F)); + list.add(new Point3f(0.36000399999999999F, 6.0000000000000002E-06F, 0.240006F)); + list.add(new Point3f(-0.120005F, -0.080004000000000006F, -0.120003F)); + list.add(new Point3f(0.42000599999999999F, 6.9999999999999999E-06F, 0.180009F)); + list.add(new Point3f(-0.14000699999999999F, -0.160001F, -0.14000199999999999F)); + list.add(new Point3f(0.48000799999999999F, 3.0000000000000001E-06F, 0.120003F)); + list.add(new Point3f(-0.16000900000000001F, -0.240006F, -0.16000600000000001F)); + list.add(new Point3f(0.54000099999999995F, 1.9999999999999999E-06F, 0.060000600000000001F)); + list.add(new Point3f(-0.180002F, -0.32000299999999998F, -0.18000099999999999F)); + list.add(new Point3f(0.60000299999999995F, 3.9999999999999998E-06F, 5.0000000000000004E-06F)); + list.add(new Point3f(-0.20000399999999999F, -0.40000599999999997F, -0.20000200000000001F)); + list.add(new Point3f(0.66000499999999995F, 6.9999999999999999E-06F, -0.060003000000000001F)); + list.add(new Point3f(-0.22000600000000001F, -0.48000900000000002F, -0.22000600000000001F)); + list.add(new Point3f(0.72000699999999995F, 7.9999999999999996E-06F, -0.120004F)); + list.add(new Point3f(-0.240008F, -0.56000399999999995F, -0.24000299999999999F)); + list.add(new Point3f(0.78000899999999995F, 5.0000000000000004E-06F, -0.180007F)); + list.add(new Point3f(-0.26000200000000001F, -0.64000699999999999F, -0.26000400000000001F)); + list.add(new Point3f(0.840001F, 7.9999999999999996E-06F, -0.24000199999999999F)); + list.add(new Point3f(-0.280003F, -0.720001F, -0.280005F)); + list.add(new Point3f(0.90000500000000005F, 3.0000000000000001E-06F, -0.30000700000000002F)); + list.add(new Point3f(-0.30000300000000002F, -0.80000499999999997F, -0.30000300000000002F)); + list.add(new Point3f(0.96000099999999999F, 1.9999999999999999E-06F, -0.36000700000000002F)); + list.add(new Point3f(-0.32000899999999999F, -0.88000100000000003F, -0.32000299999999998F)); + return list.toArray(new Point3f[list.size()]); + } +} diff --git a/gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationInspector.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationInspector.java new file mode 100644 index 0000000..9ec52f9 --- /dev/null +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationInspector.java @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2013, 2014 Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.hellblazer.voronoi3d.gui; + +import java.util.Random; + +import javax.vecmath.Point3d; + +import com.hellblazer.delaunay.Tetrahedralization; +import com.hellblazer.delaunay.Vertex; + +import javafx.application.Application; +import javafx.event.EventHandler; +import javafx.scene.DepthTest; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.PerspectiveCamera; +import javafx.scene.Scene; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseEvent; +import javafx.scene.input.ScrollEvent; +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Box; +import javafx.stage.Stage; + +/** + * Neolithic 3D viewer, based on ye venerable JavaFX 3D sample app + * + * @author hal.hildebrand + */ +public class TetrahedralizationInspector extends Application { + /** + * This is the main() you want to run from your IDE + */ + public static class Launcher { + + public static void main(String[] argv) { + TetrahedralizationInspector.main(argv); + } + } + + private static final double AXIS_LENGTH = 250.0; + private static final double CAMERA_FAR_CLIP = 10000.0; + private static final double CAMERA_INITIAL_DISTANCE = -450; + private static final double CAMERA_INITIAL_X_ANGLE = 70.0; + private static final double CAMERA_INITIAL_Y_ANGLE = 320.0; + private static final double CAMERA_NEAR_CLIP = 0.1; + private static final double CONTROL_MULTIPLIER = 0.1; + private static final double MOUSE_SPEED = 0.1; + private static final double ROTATION_SPEED = 2.0; + private static final double SHIFT_MULTIPLIER = 10.0; + private static final double TRACK_SPEED = 0.3; + + public static void main(String[] args) { + launch(args); + } + + final Xform axisGroup = new Xform(); + final PerspectiveCamera camera = new PerspectiveCamera(true); + final Xform cameraXform = new Xform(); + final Xform cameraXform2 = new Xform(); + final Xform cameraXform3 = new Xform(); + final Xform moleculeGroup = new Xform(); + double mouseDeltaX; + double mouseDeltaY; + double mouseOldX; + double mouseOldY; + double mousePosX; + double mousePosY; + final Group root = new Group(); + final Xform world = new Xform(); + private TetrahedralizationView view; + + @Override + public void start(Stage primaryStage) { + + // setUserAgentStylesheet(STYLESHEET_MODENA); + + root.getChildren().add(world); + root.setDepthTest(DepthTest.ENABLE); + + // buildScene(); + buildCamera(); + buildAxes(); + build(); + + Scene scene = new Scene(root, 1024, 768, true); + scene.setFill(Color.GREY); + handleKeyboard(scene, world); + handleMouse(scene, world); + + primaryStage.setTitle("Tetrahedralization Inspector"); + primaryStage.setScene(scene); + primaryStage.show(); + + scene.setCamera(camera); + // Attach a scroll listener + primaryStage.addEventHandler(ScrollEvent.SCROLL, event -> { + double modifier = 50.0; + double modifierFactor = 0.01; + if (event.isControlDown()) { + modifier = 1; + } + if (event.isShiftDown()) { + modifier = 100.0; + } + double z = camera.getTranslateZ(); + double newZ = z + event.getDeltaY() * modifierFactor * modifier; + camera.setTranslateZ(newZ); + }); + } + + private void build() { + final var random = new Random(666); + final var tet = new Tetrahedralization(random); + Point3d ourPoints[] = Vertex.getRandomPoints(random, 200, 10.0f, false); + for (var v : ourPoints) { + tet.insert(v); + } + view = new TetrahedralizationView(tet); + view.update(false, false, true, false, true); + moleculeGroup.getChildren().add(view); + + world.getChildren().addAll(moleculeGroup); + } + + private void buildAxes() { + final PhongMaterial redMaterial = new PhongMaterial(); + redMaterial.setDiffuseColor(Color.DARKRED); + redMaterial.setSpecularColor(Color.RED); + + final PhongMaterial greenMaterial = new PhongMaterial(); + greenMaterial.setDiffuseColor(Color.DARKGREEN); + greenMaterial.setSpecularColor(Color.GREEN); + + final PhongMaterial blueMaterial = new PhongMaterial(); + blueMaterial.setDiffuseColor(Color.DARKBLUE); + blueMaterial.setSpecularColor(Color.BLUE); + + final Box xAxis = new Box(AXIS_LENGTH, 1, 1); + final Box yAxis = new Box(1, AXIS_LENGTH, 1); + final Box zAxis = new Box(1, 1, AXIS_LENGTH); + + xAxis.setMaterial(redMaterial); + yAxis.setMaterial(greenMaterial); + zAxis.setMaterial(blueMaterial); + + axisGroup.getChildren().addAll(xAxis, yAxis, zAxis); + axisGroup.setVisible(false); + world.getChildren().addAll(axisGroup); + } + + private void buildCamera() { + root.getChildren().add(cameraXform); + cameraXform.getChildren().add(cameraXform2); + cameraXform2.getChildren().add(cameraXform3); + cameraXform3.getChildren().add(camera); + cameraXform3.setRotateZ(180.0); + + camera.setNearClip(CAMERA_NEAR_CLIP); + camera.setFarClip(CAMERA_FAR_CLIP); + camera.setTranslateZ(CAMERA_INITIAL_DISTANCE); + cameraXform.ry.setAngle(CAMERA_INITIAL_Y_ANGLE); + cameraXform.rx.setAngle(CAMERA_INITIAL_X_ANGLE); + } + + private void handleKeyboard(Scene scene, final Node root) { + scene.setOnKeyPressed(new EventHandler() { + @Override + public void handle(KeyEvent event) { + switch (event.getCode()) { + case Z: + cameraXform2.t.setX(0.0); + cameraXform2.t.setY(0.0); + camera.setTranslateZ(CAMERA_INITIAL_DISTANCE); + cameraXform.ry.setAngle(CAMERA_INITIAL_Y_ANGLE); + cameraXform.rx.setAngle(CAMERA_INITIAL_X_ANGLE); + break; + case X: + axisGroup.setVisible(!axisGroup.isVisible()); + break; + case V: + moleculeGroup.setVisible(!moleculeGroup.isVisible()); + break; + default: + break; + } + } + }); + } + + private void handleMouse(Scene scene, final Node root) { + scene.setOnMousePressed(new EventHandler() { + @Override + public void handle(MouseEvent me) { + mousePosX = me.getSceneX(); + mousePosY = me.getSceneY(); + mouseOldX = me.getSceneX(); + mouseOldY = me.getSceneY(); + } + }); + scene.setOnMouseDragged(new EventHandler() { + @Override + public void handle(MouseEvent me) { + mouseOldX = mousePosX; + mouseOldY = mousePosY; + mousePosX = me.getSceneX(); + mousePosY = me.getSceneY(); + mouseDeltaX = (mousePosX - mouseOldX); + mouseDeltaY = (mousePosY - mouseOldY); + + double modifier = 1.0; + + if (me.isControlDown()) { + modifier = CONTROL_MULTIPLIER; + } + if (me.isShiftDown()) { + modifier = SHIFT_MULTIPLIER; + } + if (me.isPrimaryButtonDown()) { + cameraXform.ry.setAngle(cameraXform.ry.getAngle() + - mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED); + cameraXform.rx.setAngle(cameraXform.rx.getAngle() + + mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED); + } else if (me.isSecondaryButtonDown()) { + double z = camera.getTranslateZ(); + double newZ = z + mouseDeltaX * MOUSE_SPEED * modifier; + camera.setTranslateZ(newZ); + } else if (me.isMiddleButtonDown()) { + cameraXform2.t.setX(cameraXform2.t.getX() + mouseDeltaX * MOUSE_SPEED * modifier * TRACK_SPEED); + cameraXform2.t.setY(cameraXform2.t.getY() + mouseDeltaY * MOUSE_SPEED * modifier * TRACK_SPEED); + } + } + }); + } +} diff --git a/gui/src/main/java/com/hellblazer/delaunay/gui/TetrahedralizationView.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationView.java similarity index 68% rename from gui/src/main/java/com/hellblazer/delaunay/gui/TetrahedralizationView.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationView.java index 8f4abb2..51da2e8 100644 --- a/gui/src/main/java/com/hellblazer/delaunay/gui/TetrahedralizationView.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/TetrahedralizationView.java @@ -17,13 +17,13 @@ * along with this program. If not, see . */ -package com.hellblazer.delaunay.gui; +package com.hellblazer.voronoi3d.gui; import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.vecmath.Point3f; +import javax.vecmath.Tuple3d; import com.hellblazer.delaunay.Tetrahedralization; import com.hellblazer.delaunay.Tetrahedron; @@ -43,11 +43,13 @@ public class TetrahedralizationView extends GraphicsView { private static final PhongMaterial COLOR_OF_HIGHLIGHTED_REGION = null; private final Group delaunay = new Group(); - private final Set fourCorners = new HashSet<>(); + private final Group delaunayFaces = new Group(); + private final Set fourCorners = new HashSet<>(); private final Group highlightedRegions = new Group(); private final Tetrahedralization tetrahedralization; private final Group vertexes = new Group(); private final Group voronoi = new Group(); + private final Group voronoiFaces = new Group(); public TetrahedralizationView() { this(new Tetrahedralization()); @@ -57,7 +59,7 @@ public TetrahedralizationView(Tetrahedralization t) { super(); tetrahedralization = t; for (Vertex v : tetrahedralization.getUniverse()) { - fourCorners.add(v.asPoint3f()); + fourCorners.add(v); } updateDiagram(); } @@ -71,57 +73,63 @@ public void highlightRegions(boolean highlight, List vertices) { highlightedRegions.getChildren().clear(); if (highlight) { for (Vertex v : vertices) { - render(tetrahedralization.getVoronoiRegion(v), COLOR_OF_HIGHLIGHTED_REGION, true, highlightedRegions); + render(v.getVoronoiRegion(), COLOR_OF_HIGHLIGHTED_REGION, true, highlightedRegions); } - displaySpheres(vertices, 0.03F, COLOR_OF_HIGHLIGHTED_REGION, highlightedRegions); + displaySpheres(vertices.stream(), 0.03F, COLOR_OF_HIGHLIGHTED_REGION, highlightedRegions); } getChildren().add(highlightedRegions); } - public void update(boolean showVD, boolean showDT, boolean showAllPoints) { + public void update(boolean showVD, boolean showVDFaces, boolean showDT, boolean showDTFaces, + boolean showAllPoints) { var children = getChildren(); children.clear(); if (showVD) { children.add(voronoi); } + if (showVDFaces) { + children.add(voronoiFaces); + } if (showDT) { children.add(delaunay); } + if (showDTFaces) { + children.add(delaunayFaces); + } if (showAllPoints) { children.add(vertexes); } } public void updateDiagram() { - var tetrahedrons = new HashSet(); - var vertices = new HashSet(); - tetrahedralization.traverse(tetrahedrons, vertices); voronoi.getChildren().clear(); + voronoiFaces.getChildren().clear(); delaunay.getChildren().clear(); - for (Tetrahedron t : tetrahedrons) { - for (Point3f[] face : t.getFacesCoordinates()) { + delaunayFaces.getChildren().clear(); + for (Tetrahedron t : tetrahedralization.getTetrahedrons()) { + for (var face : t.getFaces()) { render(face, Colors.yellowMaterial, false, delaunay); + render(face, Colors.yellowMaterial, true, delaunayFaces); } } - for (Vertex v : vertices) { - for (Point3f[] face : tetrahedralization.getVoronoiRegion(v)) { + for (Vertex v : tetrahedralization.getVertices()) { + for (var face : v.getVoronoiRegion()) { render(face, Colors.cyanMaterial, false, voronoi); + render(face, Colors.cyanMaterial, true, voronoiFaces); } } - displaySpheres(vertices, 0.01, Colors.yellowMaterial, vertexes); + displaySpheres(tetrahedralization.getVertices().stream(), 0.07, Colors.yellowMaterial, vertexes); } @Override - protected boolean isAuxillary(Point3f[] face) { + protected boolean isAuxillary(Tuple3d[] face) { if (face.length < 3) { return true; } for (var v : face) { if (fourCorners.contains(v)) { return true; - } else if (v.distance(new Point3f()) > 1000000) { - return true; } } return false; diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Xform.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/Xform.java similarity index 77% rename from gui/src/main/java/com/javafx/experiments/jfx3dviewer/Xform.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/Xform.java index 8cf12a6..79eefb6 100644 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Xform.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/Xform.java @@ -1,236 +1,229 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.scene.Group; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Translate; - -public class Xform extends Group { - - public enum RotateOrder { - XYZ, - XZY, - YXZ, - YZX, - ZXY, - ZYX - } - - public Translate ip = new Translate(); - public Translate p = new Translate(); - public Rotate rx = new Rotate(); - public Rotate ry = new Rotate(); - public Rotate rz = new Rotate(); - public Scale s = new Scale(); - public Translate t = new Translate(); - { - rx.setAxis(Rotate.X_AXIS); - } - { - ry.setAxis(Rotate.Y_AXIS); - } - { - rz.setAxis(Rotate.Z_AXIS); - } - - public Xform() { - super(); - getTransforms().addAll(t, rz, ry, rx, s); - } - - public Xform(RotateOrder rotateOrder) { - super(); - // choose the order of rotations based on the rotateOrder - switch (rotateOrder) { - case XYZ: - getTransforms().addAll(t, p, rz, ry, rx, s, ip); - break; - case XZY: - getTransforms().addAll(t, p, ry, rz, rx, s, ip); - break; - case YXZ: - getTransforms().addAll(t, p, rz, rx, ry, s, ip); - break; - case YZX: - getTransforms().addAll(t, p, rx, rz, ry, s, ip); // For Camera - break; - case ZXY: - getTransforms().addAll(t, p, ry, rx, rz, s, ip); - break; - case ZYX: - getTransforms().addAll(t, p, rx, ry, rz, s, ip); - break; - } - } - - public void debug() { - System.out.println("t = (" + t.getX() + ", " + t.getY() + ", " - + t.getZ() + ") " + "r = (" + rx.getAngle() + ", " - + ry.getAngle() + ", " + rz.getAngle() + ") " - + "s = (" + s.getX() + ", " + s.getY() + ", " - + s.getZ() + ") " + "p = (" + p.getX() + ", " - + p.getY() + ", " + p.getZ() + ") " + "ip = (" - + ip.getX() + ", " + ip.getY() + ", " + ip.getZ() - + ")"); - } - - public void reset() { - t.setX(0.0); - t.setY(0.0); - t.setZ(0.0); - rx.setAngle(0.0); - ry.setAngle(0.0); - rz.setAngle(0.0); - s.setX(1.0); - s.setY(1.0); - s.setZ(1.0); - p.setX(0.0); - p.setY(0.0); - p.setZ(0.0); - ip.setX(0.0); - ip.setY(0.0); - ip.setZ(0.0); - } - - public void resetTSP() { - t.setX(0.0); - t.setY(0.0); - t.setZ(0.0); - s.setX(1.0); - s.setY(1.0); - s.setZ(1.0); - p.setX(0.0); - p.setY(0.0); - p.setZ(0.0); - ip.setX(0.0); - ip.setY(0.0); - ip.setZ(0.0); - } - - public void setPivot(double x, double y, double z) { - p.setX(x); - p.setY(y); - p.setZ(z); - ip.setX(-x); - ip.setY(-y); - ip.setZ(-z); - } - - public void setRotate(double x, double y, double z) { - rx.setAngle(x); - ry.setAngle(y); - rz.setAngle(z); - } - - public void setRotateX(double x) { - rx.setAngle(x); - } - - public void setRotateY(double y) { - ry.setAngle(y); - } - - public void setRotateZ(double z) { - rz.setAngle(z); - } - - public void setRx(double x) { - rx.setAngle(x); - } - - public void setRy(double y) { - ry.setAngle(y); - } - - public void setRz(double z) { - rz.setAngle(z); - } - - public void setScale(double scaleFactor) { - s.setX(scaleFactor); - s.setY(scaleFactor); - s.setZ(scaleFactor); - } - - public void setScale(double x, double y, double z) { - s.setX(x); - s.setY(y); - s.setZ(z); - } - - // Cannot override these methods as they are final: - // public void setScaleX(double x) { s.setX(x); } - // public void setScaleY(double y) { s.setY(y); } - // public void setScaleZ(double z) { s.setZ(z); } - // Use these methods instead: - public void setSx(double x) { - s.setX(x); - } - - public void setSy(double y) { - s.setY(y); - } - - public void setSz(double z) { - s.setZ(z); - } - - public void setTranslate(double x, double y) { - t.setX(x); - t.setY(y); - } - - public void setTranslate(double x, double y, double z) { - t.setX(x); - t.setY(y); - t.setZ(z); - } - - // Cannot override these methods as they are final: - // public void setTranslateX(double x) { t.setX(x); } - // public void setTranslateY(double y) { t.setY(y); } - // public void setTranslateZ(double z) { t.setZ(z); } - // Use these methods instead: - public void setTx(double x) { - t.setX(x); - } - - public void setTy(double y) { - t.setY(y); - } - - public void setTz(double z) { - t.setZ(z); - } -} +/* + * Copyright (c) 2013, 2014 Oracle and/or its affiliates. + * All rights reserved. Use is subject to license terms. + * + * This file is available and licensed under the following license: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.hellblazer.voronoi3d.gui; + +import javafx.scene.Group; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Scale; +import javafx.scene.transform.Translate; + +public class Xform extends Group { + + public enum RotateOrder { + XYZ, XZY, YXZ, YZX, ZXY, ZYX + } + + public Translate ip = new Translate(); + public Translate p = new Translate(); + public Rotate rx = new Rotate(); + public Rotate ry = new Rotate(); + public Rotate rz = new Rotate(); + public Scale s = new Scale(); + public Translate t = new Translate(); + { + rx.setAxis(Rotate.X_AXIS); + } + { + ry.setAxis(Rotate.Y_AXIS); + } + { + rz.setAxis(Rotate.Z_AXIS); + } + + public Xform() { + super(); + getTransforms().addAll(t, rz, ry, rx, s); + } + + public Xform(RotateOrder rotateOrder) { + super(); + // choose the order of rotations based on the rotateOrder + switch (rotateOrder) { + case XYZ: + getTransforms().addAll(t, p, rz, ry, rx, s, ip); + break; + case XZY: + getTransforms().addAll(t, p, ry, rz, rx, s, ip); + break; + case YXZ: + getTransforms().addAll(t, p, rz, rx, ry, s, ip); + break; + case YZX: + getTransforms().addAll(t, p, rx, rz, ry, s, ip); // For Camera + break; + case ZXY: + getTransforms().addAll(t, p, ry, rx, rz, s, ip); + break; + case ZYX: + getTransforms().addAll(t, p, rx, ry, rz, s, ip); + break; + } + } + + public void reset() { + t.setX(0.0); + t.setY(0.0); + t.setZ(0.0); + rx.setAngle(0.0); + ry.setAngle(0.0); + rz.setAngle(0.0); + s.setX(1.0); + s.setY(1.0); + s.setZ(1.0); + p.setX(0.0); + p.setY(0.0); + p.setZ(0.0); + ip.setX(0.0); + ip.setY(0.0); + ip.setZ(0.0); + } + + public void resetTSP() { + t.setX(0.0); + t.setY(0.0); + t.setZ(0.0); + s.setX(1.0); + s.setY(1.0); + s.setZ(1.0); + p.setX(0.0); + p.setY(0.0); + p.setZ(0.0); + ip.setX(0.0); + ip.setY(0.0); + ip.setZ(0.0); + } + + public void setPivot(double x, double y, double z) { + p.setX(x); + p.setY(y); + p.setZ(z); + ip.setX(-x); + ip.setY(-y); + ip.setZ(-z); + } + + public void setRotate(double x, double y, double z) { + rx.setAngle(x); + ry.setAngle(y); + rz.setAngle(z); + } + + public void setRotateX(double x) { + rx.setAngle(x); + } + + public void setRotateY(double y) { + ry.setAngle(y); + } + + public void setRotateZ(double z) { + rz.setAngle(z); + } + + public void setRx(double x) { + rx.setAngle(x); + } + + public void setRy(double y) { + ry.setAngle(y); + } + + public void setRz(double z) { + rz.setAngle(z); + } + + public void setScale(double scaleFactor) { + s.setX(scaleFactor); + s.setY(scaleFactor); + s.setZ(scaleFactor); + } + + public void setScale(double x, double y, double z) { + s.setX(x); + s.setY(y); + s.setZ(z); + } + + // Cannot override these methods as they are final: + // public void setScaleX(double x) { s.setX(x); } + // public void setScaleY(double y) { s.setY(y); } + // public void setScaleZ(double z) { s.setZ(z); } + // Use these methods instead: + public void setSx(double x) { + s.setX(x); + } + + public void setSy(double y) { + s.setY(y); + } + + public void setSz(double z) { + s.setZ(z); + } + + public void setTranslate(double x, double y) { + t.setX(x); + t.setY(y); + } + + public void setTranslate(double x, double y, double z) { + t.setX(x); + t.setY(y); + t.setZ(z); + } + + // Cannot override these methods as they are final: + // public void setTranslateX(double x) { t.setX(x); } + // public void setTranslateY(double y) { t.setY(y); } + // public void setTranslateZ(double z) { t.setZ(z); } + // Use these methods instead: + public void setTx(double x) { + t.setX(x); + } + + public void setTy(double y) { + t.setY(y); + } + + public void setTz(double z) { + t.setZ(z); + } + + @Override + public String toString() { + return "Xform[t = (" + t.getX() + ", " + t.getY() + ", " + t.getZ() + ") " + "r = (" + rx.getAngle() + ", " + + ry.getAngle() + ", " + rz.getAngle() + ") " + "s = (" + s.getX() + ", " + s.getY() + ", " + s.getZ() + ") " + + "p = (" + p.getX() + ", " + p.getY() + ", " + p.getZ() + ") " + "ip = (" + ip.getX() + ", " + ip.getY() + + ", " + ip.getZ() + ")]"; + } +} diff --git a/gui/src/main/java/mesh/Edge.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Edge.java similarity index 99% rename from gui/src/main/java/mesh/Edge.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Edge.java index 6bf813a..e2bb4ba 100644 --- a/gui/src/main/java/mesh/Edge.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Edge.java @@ -1,4 +1,4 @@ -package mesh; +package com.hellblazer.voronoi3d.gui.mesh; import java.util.ArrayList; import java.util.Arrays; diff --git a/gui/src/main/java/mesh/Face.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Face.java similarity index 99% rename from gui/src/main/java/mesh/Face.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Face.java index 2303030..deed9a6 100644 --- a/gui/src/main/java/mesh/Face.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Face.java @@ -1,4 +1,4 @@ -package mesh; +package com.hellblazer.voronoi3d.gui.mesh; import java.util.ArrayList; import java.util.Arrays; diff --git a/gui/src/main/java/mesh/Line.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Line.java similarity index 99% rename from gui/src/main/java/mesh/Line.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Line.java index e000f7e..7d1e27a 100644 --- a/gui/src/main/java/mesh/Line.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Line.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mesh; +package com.hellblazer.voronoi3d.gui.mesh; import javafx.geometry.Point3D; import javafx.scene.shape.Cylinder; diff --git a/gui/src/main/java/mesh/Mesh.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Mesh.java similarity index 99% rename from gui/src/main/java/mesh/Mesh.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Mesh.java index 8a61ada..b64ec3c 100644 --- a/gui/src/main/java/mesh/Mesh.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/Mesh.java @@ -1,4 +1,4 @@ -package mesh; +package com.hellblazer.voronoi3d.gui.mesh; import java.io.File; import java.io.FileWriter; diff --git a/gui/src/main/java/mesh/PolyLine.java b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/PolyLine.java similarity index 97% rename from gui/src/main/java/mesh/PolyLine.java rename to gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/PolyLine.java index 1e19155..5fa6373 100644 --- a/gui/src/main/java/mesh/PolyLine.java +++ b/gui/src/main/java/com/hellblazer/voronoi3d/gui/mesh/PolyLine.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package mesh; +package com.hellblazer.voronoi3d.gui.mesh; import java.util.ArrayList; import java.util.List; diff --git a/gui/src/main/java/com/javafx/experiments/exporters/fxml/FXMLExporter.java b/gui/src/main/java/com/javafx/experiments/exporters/fxml/FXMLExporter.java deleted file mode 100644 index ddbb3ff..0000000 --- a/gui/src/main/java/com/javafx/experiments/exporters/fxml/FXMLExporter.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.exporters.fxml; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javafx.collections.ObservableArray; -import javafx.geometry.Point3D; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.paint.Color; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.Box; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.Shape3D; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Affine; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Transform; -import javafx.scene.transform.Translate; - -/** Export a 3D MeshView to FXML file. */ -public class FXMLExporter { - - private class FXML { - private class Entry { - String key; - String value; - - public Entry(String key, String value) { - this.key = key; - this.value = value; - } - } - - List nested; - List properties; - Object value; - - private String tagName; - - public FXML(Class cls) { - String fullName = simpleNames.get(cls.getSimpleName()); - if (fullName == null) { - - // this short name is not used, so adding it to imports and - // to shortNames map - fullName = cls.getName(); - imports.add(cls.getPackage() - .getName()); - simpleNames.put(cls.getSimpleName(), fullName); - tagName = cls.getSimpleName(); - } else if (!fullName.equals(cls.getName())) { - - // short name is already used for some other class so we have - // to use full name - tagName = cls.getName(); - } else { - - // short name matches this class - tagName = cls.getSimpleName(); - } - } - - public FXML(String tagName) { - this.tagName = tagName; - } - - void addProperty(String key, String value) { - if (properties == null) { - properties = new ArrayList<>(); - } - properties.add(new Entry(key, value)); - } - - void export(String indent) { - printWriter.append(indent) - .append('<') - .append(tagName); - if (properties != null) { - for (Entry entry : properties) { - printWriter.append(' ') - .append(entry.key) - .append("=\"") - .append(entry.value) - .append("\""); - } - } - if (nested != null || value != null) { - printWriter.append(">\n"); - String indent1 = indent + " "; - if (nested != null) { - for (FXML fxml : nested) { - fxml.export(indent1); - } - } - if (value != null) { - String toString; - if (value instanceof ObservableArray) { - toString = value.toString(); - } else { - throw new UnsupportedOperationException("Only ObservableArrays are currently supported"); - } - printWriter.append(indent1) - .append(toString.substring(1, - toString.length() - - 1)) - .append("\n"); - } - printWriter.append(indent) - .append("\n"); - } else { - printWriter.append("/>\n"); - } - } - - void setValue(Object value) { - this.value = value; - } - - private void addChild(FXML fxml) { - if (fxml == null) { - return; - } - if (nested == null) { - nested = new ArrayList<>(); - } - nested.add(fxml); - } - - private FXML addContainer(String containerTag) { - if (nested != null) { - for (FXML n : nested) { - if (n.tagName.equals(containerTag)) { - return n; - } - } - } - FXML fxml = new FXML(containerTag); - addChild(fxml); - return fxml; - } - } - - private class Property { - Method getter; - String name; - - public Property(Method getter, String name) { - this.getter = getter; - this.name = name; - } - } - - private Set imports = new TreeSet<>(); - - private PrintWriter printWriter; - - private Map, List> propertiesCache = new HashMap<>(); - - private Map simpleNames = new HashMap<>(); - - public FXMLExporter(OutputStream outputStream) { - printWriter = new PrintWriter(outputStream); - } - - public FXMLExporter(String filename) { - File file = new File(filename); - try { - printWriter = new PrintWriter(file); - System.out.println("Saving FMXL to " + file.getAbsolutePath()); - } catch (FileNotFoundException ex) { - throw new RuntimeException("Failed to export FXML to " - + file.getAbsolutePath(), ex); - } - } - - public void export(Node node) { - printWriter.println("\n"); - FXML fxmlTree = exportToFXML(node); - for (String importString : imports) { - printWriter.println(""); - } - printWriter.println(); - fxmlTree.export(""); - printWriter.close(); - } - - private FXML exportToFXML(Object object) { - if (object instanceof Transform && ((Transform) object).isIdentity()) { - return null; - } - - FXML fxml = new FXML(object.getClass()); - - List properties = propertiesCache.get(object.getClass()); - if (properties == null) { - properties = getProperties(object.getClass()); - propertiesCache.put(object.getClass(), properties); - } - - for (Property property : properties) { - try { - Object[] parameters = new Object[property.getter.getParameterTypes().length]; - Object value = property.getter.invoke(object, parameters); - if (value != null) { - if (value instanceof Collection) { - Collection collection = (Collection) value; - if (!collection.isEmpty()) { - FXML container = fxml.addContainer(property.name); - for (Object item : collection) { - container.addChild(exportToFXML(item)); - } - } - } else if (value instanceof ObservableArray) { - int length = ((ObservableArray) value).size(); - if (length > 0) { - FXML container = fxml.addContainer(property.name); - container.setValue(value); - } - } else if (property.getter.getReturnType() - .isPrimitive() - || String.class.equals(value.getClass()) - || Color.class.equals(value.getClass())) { - fxml.addProperty(property.name, String.valueOf(value)); - } else { - FXML container = fxml.addContainer(property.name); - container.addChild(exportToFXML(value)); - } - } - } catch (IllegalAccessException | IllegalArgumentException - | InvocationTargetException ex) { - Logger.getLogger(FXMLExporter.class.getName()) - .log(Level.SEVERE, null, ex); - } - } - - return fxml; - } - - private List getProperties(Class aClass) { - List res = new ArrayList<>(); - try { - if (Point3D.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getX"), "x")); - res.add(new Property(aClass.getMethod("getY"), "y")); - res.add(new Property(aClass.getMethod("getZ"), "z")); - } - if (Translate.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getX"), "x")); - res.add(new Property(aClass.getMethod("getY"), "y")); - res.add(new Property(aClass.getMethod("getZ"), "z")); - } - if (Rotate.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getAngle"), "angle")); - res.add(new Property(aClass.getMethod("getAxis"), "axis")); - } - if (Affine.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getMxx"), "mxx")); - res.add(new Property(aClass.getMethod("getMxy"), "mxy")); - res.add(new Property(aClass.getMethod("getMxz"), "mxz")); - res.add(new Property(aClass.getMethod("getMyx"), "myx")); - res.add(new Property(aClass.getMethod("getMyy"), "myy")); - res.add(new Property(aClass.getMethod("getMyz"), "myz")); - res.add(new Property(aClass.getMethod("getMzx"), "mzx")); - res.add(new Property(aClass.getMethod("getMzy"), "mzy")); - res.add(new Property(aClass.getMethod("getMzz"), "mzz")); - res.add(new Property(aClass.getMethod("getTx"), "tx")); - res.add(new Property(aClass.getMethod("getTy"), "ty")); - res.add(new Property(aClass.getMethod("getTz"), "tz")); - } - if (PhongMaterial.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getDiffuseColor"), - "diffuseColor")); - } - if (Node.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getId"), "id")); - res.add(new Property(aClass.getMethod("getTransforms"), - "transforms")); - } - if (Parent.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getChildrenUnmodifiable"), - "children")); - } - if (Shape3D.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getMaterial"), - "material")); - } - if (Box.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getWidth"), "width")); - res.add(new Property(aClass.getMethod("getHeight"), "height")); - res.add(new Property(aClass.getMethod("getDepth"), "depth")); - } - if (MeshView.class.equals(aClass)) { - res.add(new Property(aClass.getMethod("getMesh"), "mesh")); - } - if (TriangleMesh.class.isAssignableFrom(aClass)) { - res.add(new Property(aClass.getMethod("getPoints"), "points")); - res.add(new Property(aClass.getMethod("getTexCoords"), - "texCoords")); - res.add(new Property(aClass.getMethod("getFaces"), "faces")); - res.add(new Property(aClass.getMethod("getFaceSmoothingGroups"), - "faceSmoothingGroups")); - } - } catch (NoSuchMethodException | SecurityException ex) { - Logger.getLogger(FXMLExporter.class.getName()) - .log(Level.SEVERE, null, ex); - } - return res; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/exporters/javasource/JavaSourceExporter.java b/gui/src/main/java/com/javafx/experiments/exporters/javasource/JavaSourceExporter.java deleted file mode 100644 index 5ddce02..0000000 --- a/gui/src/main/java/com/javafx/experiments/exporters/javasource/JavaSourceExporter.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.exporters.javasource; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.javafx.experiments.utils3d.animation.NumberTangentInterpolator; -import com.javafx.experiments.utils3d.animation.SplineInterpolator; -import com.javafx.experiments.utils3d.animation.TickCalculation; - -import javafx.animation.Interpolator; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.beans.value.WritableValue; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.image.Image; -import javafx.scene.paint.Color; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Transform; -import javafx.scene.transform.Translate; - -/** - * A exporter for 3D Models and animations that creates a Java Source file. - */ -public class JavaSourceExporter { - private static String computePackageName(String baseUrl) { - // remove protocol from baseUrl - System.out.println("JavaSourceExporter.computePackageName baseUrl = " + baseUrl); - baseUrl = baseUrl.replaceAll("^[a-z]+:/+", "/"); - System.out.println("baseUrl = " + baseUrl); - // try and work out package name from file - StringBuilder packageName = new StringBuilder(); - String[] pathSegments = baseUrl.split(File.separatorChar == '\\' ? "\\\\" : "/"); - System.out.println("pathSegments = " + Arrays.toString(pathSegments)); - loop: for (int i = pathSegments.length - 1; i >= 0; i--) { - switch (pathSegments[i]) { - case "com": - case "org": - case "net": - packageName.insert(0, pathSegments[i]); - break loop; - case "src": - packageName.deleteCharAt(0); - break loop; - case "main": - if ("src".equals(pathSegments[i - 1])) { - packageName.deleteCharAt(0); - break loop; - } - default: - packageName.insert(0, '.' + pathSegments[i]); - break; - } - // if we get all way to root of file system then we have failed - if (i == 0) { - packageName = null; - } - } - System.out.println(" packageName = " + packageName); - return packageName == null ? null : packageName.toString(); - } - - private final String baseUrl; - private final String className; - private final boolean hasTimeline; - private int materialCount = 0; - private int meshCount = 0; - private int meshViewCount = 0; - private int methodCount = 1; - private StringBuilder nodeCode = new StringBuilder(); - private int nodeCount = 0; - private final File outputFile; - private final String packageName; - private int rotateCount = 0; - private int scaleCount = 0; - private StringBuilder timelineCode = new StringBuilder(); - private int translateCount = 0; - - private Map, String> writableVarMap = new HashMap<>(); - - public JavaSourceExporter(String baseUrl, Node rootNode, Timeline timeline, File outputFile) { - this(baseUrl, rootNode, timeline, computePackageName(baseUrl), outputFile); - } - - public JavaSourceExporter(String baseUrl, Node rootNode, Timeline timeline, String packageName, File outputFile) { - this.baseUrl = (baseUrl.charAt(baseUrl.length() - 1) == '/') ? baseUrl.replaceAll("/+", "/") - : baseUrl.replaceAll("/+", "/") + '/'; - this.hasTimeline = timeline != null; - this.className = outputFile.getName().substring(0, outputFile.getName().lastIndexOf('.')); - this.packageName = packageName; - this.outputFile = outputFile; - process(" ", rootNode); - if (hasTimeline) { - process(" ", timeline); - } - } - - public void export() { - try { - BufferedWriter out = new BufferedWriter(new FileWriter(outputFile)); - // BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out)); - StringBuilder nodeVars = new StringBuilder(); - nodeVars.append(" private static Node "); - for (int i = 0; i < nodeCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("NODE_" + i); - } - nodeVars.append(";\n"); - nodeVars.append(" private static TriangleMesh "); - for (int i = 0; i < meshCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("MESH_" + i); - } - nodeVars.append(";\n"); - if (translateCount > 0) { - nodeVars.append(" private static Translate "); - for (int i = 0; i < translateCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("TRANS_" + i); - } - nodeVars.append(";\n"); - } - if (rotateCount > 0) { - nodeVars.append(" private static Rotate "); - for (int i = 0; i < rotateCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("ROT_" + i); - } - nodeVars.append(";\n"); - } - if (scaleCount > 0) { - nodeVars.append(" private static Scale "); - for (int i = 0; i < scaleCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("SCALE_" + i); - } - nodeVars.append(";\n"); - } - nodeVars.append(" public static final MeshView[] MESHVIEWS = new MeshView[]{ "); - for (int i = 0; i < meshViewCount; i++) { - if (i != 0) { - nodeVars.append(','); - } - nodeVars.append("new MeshView()"); - } - nodeVars.append("};\n"); - // nodeVars.append(" public static final MeshView "); - // for (int i=0; i MESHVIEW_MAP;\n"); - if (hasTimeline) { - nodeVars.append(" public static final Timeline TIMELINE = new Timeline();\n"); - } - StringBuilder methodCode = new StringBuilder(); - for (int m = 0; m < methodCount; m++) { - methodCode.append(" method" + m + "();\n"); - } - - if (packageName != null) { - out.write("package " + packageName + ";\n\n"); - } - out.write("import java.util.*;\n" + "import javafx.util.Duration;\n" + "import javafx.animation.*;\n" - + "import javafx.scene.*;\n" + "import javafx.scene.paint.*;\n" + "import javafx.scene.image.*;\n" - + "import javafx.scene.shape.*;\n" + "import javafx.scene.transform.*;\n\n" + "public class " - + className + " {\n" + nodeVars + " // ======== NODE CODE ===============\n" - + " private static void method0(){\n" + nodeCode + " }\n" + " static {\n" + methodCode - + " // ======== TIMELINE CODE ===============\n" + timelineCode - + " // ======== SET PUBLIC VARS ===============\n" - + " Map meshViewMap = new HashMap();\n" - + " for (MeshView meshView: MESHVIEWS) meshViewMap.put(meshView.getId(),meshView);\n" - + " MESHVIEW_MAP = Collections.unmodifiableMap(meshViewMap);\n" + " ROOT = NODE_0;\n" - + " }\n" + "}\n"); - - out.flush(); - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private int process(String indent, Group node) { - final int index = nodeCount++; - final String varName = "NODE_" + index; - List childIndex = new ArrayList<>(); - for (int i = 0; i < node.getChildren().size(); i++) { - Node child = node.getChildren().get(i); - childIndex.add(process(indent, child)); - } - nodeCode.append(indent + varName + " = new Group("); - for (int i = 0; i < childIndex.size(); i++) { - if (i != 0) { - nodeCode.append(','); - } - nodeCode.append("NODE_" + childIndex.get(i)); - } - nodeCode.append(");\n"); - processNodeTransforms(indent, varName, node); - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - return index; - } - - private int process(String indent, MeshView node) { - final int index = nodeCount++; - final String varName = "NODE_" + index; - final int meshViewIndex = meshViewCount++; - final String meshViewVarName = "MESHVIEWS[" + meshViewIndex + "]"; - // nodeCode.append(indent+meshViewVarName+" = new MeshView();\n"); - nodeCode.append(indent + varName + " = " + meshViewVarName + ";\n"); - if (node.getId() != null) { - nodeCode.append(indent + meshViewVarName + ".setId(\"" + node.getId() + "\");\n"); - } - nodeCode.append(indent + meshViewVarName + ".setCullFace(CullFace." + node.getCullFace().name() + ");\n"); - processNodeTransforms(indent, meshViewVarName, node); - process(indent, meshViewVarName, (PhongMaterial) node.getMaterial()); - process(indent, meshViewVarName, (TriangleMesh) node.getMesh()); - return index; - } - - private int process(String indent, Node node) { - if (node instanceof MeshView) { - return process(indent, (MeshView) node); - } else if (node instanceof Group) { - return process(indent, (Group) node); - } else { - throw new UnsupportedOperationException("Found unknown node type: " + node.getClass().getName()); - } - } - - private void process(String indent, String varName, PhongMaterial material) { - final int index = materialCount++; - final String materialName = "MATERIAL_" + index; - - nodeCode.append(indent + "PhongMaterial " + materialName + " = new PhongMaterial();\n"); - nodeCode.append(indent + materialName + ".setDiffuseColor(" + toCode(material.getDiffuseColor()) + ");\n"); - String specColor = toCode(material.getSpecularColor()); - if (specColor != null) { - nodeCode.append(indent + materialName + ".setSpecularColor(" + specColor + ");\n"); - } - nodeCode.append(indent + materialName + ".setSpecularPower(" + material.getSpecularPower() + ");\n"); - if (material.getDiffuseMap() != null) { - nodeCode.append(indent + "try {\n"); - nodeCode.append(indent + " " + materialName + ".setDiffuseMap(" + toString(material.getDiffuseMap()) - + ");\n"); - nodeCode.append(indent + "} catch (NullPointerException npe) {\n"); - nodeCode.append(indent + " System.err.println(\"Could not load texture resource [" - + material.getDiffuseMap().getUrl() + "]\");\n"); - nodeCode.append(indent + "}\n"); - } - if (material.getBumpMap() != null) { - nodeCode.append(indent + materialName + ".setBumpMap(" + toString(material.getBumpMap()) + ");\n"); - } - if (material.getSpecularMap() != null) { - nodeCode.append(indent + materialName + ".setSpecularMap()(" + toString(material.getSpecularMap()) - + ");\n"); - } - if (material.getSelfIlluminationMap() != null) { - nodeCode.append(indent + materialName + ".setSelfIlluminationMap()(" - + toString(material.getSelfIlluminationMap()) + ");\n"); - } - nodeCode.append(indent + varName + ".setMaterial(" + materialName + ");\n"); - } - - private void process(String indent, String varName, TriangleMesh mesh) { - final int index = meshCount++; - final String meshName = "MESH_" + index; - - nodeCode.append(indent + meshName + " = new TriangleMesh();\n"); - nodeCode.append(indent + varName + ".setMesh(" + meshName + ");\n"); - - nodeCode.append(indent + meshName + ".getPoints().ensureCapacity(" + mesh.getPoints().size() + ");\n"); - nodeCode.append(indent + meshName + ".getPoints().addAll("); - for (int i = 0; i < mesh.getPoints().size(); i++) { - if (i != 0) { - nodeCode.append(','); - } - nodeCode.append(mesh.getPoints().get(i) + "f"); - } - nodeCode.append(");\n"); - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - nodeCode.append(indent + meshName + ".getTexCoords().ensureCapacity(" + mesh.getTexCoords().size() + ");\n"); - nodeCode.append(indent + meshName + ".getTexCoords().addAll("); - for (int i = 0; i < mesh.getTexCoords().size(); i++) { - if (i != 0) { - nodeCode.append(','); - } - nodeCode.append(mesh.getTexCoords().get(i) + "f"); - } - nodeCode.append(");\n"); - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - nodeCode.append(indent + meshName + ".getFaces().ensureCapacity(" + mesh.getFaces().size() + ");\n"); - nodeCode.append(indent + meshName + ".getFaces().addAll("); - for (int i = 0; i < mesh.getFaces().size(); i++) { - if ((i % 5000) == 0 && i > 0) { - nodeCode.append(");\n"); - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - nodeCode.append(indent + meshName + ".getFaces().addAll("); - } else if (i != 0) { - nodeCode.append(','); - } - nodeCode.append(mesh.getFaces().get(i)); - } - nodeCode.append(");\n"); - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - nodeCode.append(indent + meshName + ".getFaceSmoothingGroups().ensureCapacity(" - + mesh.getFaceSmoothingGroups().size() + ");\n"); - nodeCode.append(indent + meshName + ".getFaceSmoothingGroups().addAll("); - for (int i = 0; i < mesh.getFaceSmoothingGroups().size(); i++) { - if (i != 0) { - nodeCode.append(','); - } - nodeCode.append(mesh.getFaceSmoothingGroups().get(i)); - } - nodeCode.append(");\n"); - - // nodeCode.append(indent+varName+".setMesh("+process((TriangleMesh)node.getMesh())+");\n"); - } - - private void process(String indent, Timeline timeline) { - int count = 0; - for (KeyFrame keyFrame : timeline.getKeyFrames()) { - if (keyFrame.getValues().isEmpty()) { - continue; - } - nodeCode.append(indent + "TIMELINE.getKeyFrames().add(new KeyFrame(Duration.millis(" - + keyFrame.getTime().toMillis() + "d),\n"); - boolean firstKeyValue = true; - for (KeyValue keyValue : keyFrame.getValues()) { - if (firstKeyValue) { - firstKeyValue = false; - } else { - nodeCode.append(",\n"); - } - String var = writableVarMap.get(keyValue.getTarget()); - if (var == null) { - System.err.println("Failed to find writable value in map for : " + keyValue.getTarget()); - } - nodeCode.append(indent + " new KeyValue(" + var + "," + keyValue.getEndValue() + "," - + toString(keyValue.getInterpolator()) + ")"); - } - nodeCode.append("\n" + indent + "));\n"); - - if (count > 0 && ((count % 10) == 0)) { - nodeCode.append(" }\n private static void method" + (methodCount++) + "(){\n"); - } - count++; - } - } - - private void processNodeTransforms(String indent, String varName, Node node) { - if (node.getTranslateX() != 0) { - nodeCode.append(indent + varName + ".setTranslateX(" + node.getTranslateX() + ");\n"); - } - if (node.getTranslateY() != 0) { - nodeCode.append(indent + varName + ".setTranslateY(" + node.getTranslateY() + ");\n"); - } - if (node.getTranslateZ() != 0) { - nodeCode.append(indent + varName + ".setTranslateZ(" + node.getTranslateZ() + ");\n"); - } - if (node.getRotate() != 0) { - nodeCode.append(indent + varName + ".setRotate(" + node.getRotate() + ");\n"); - } - if (!node.getTransforms().isEmpty()) { - nodeCode.append(indent + varName + ".getTransforms().addAll(\n"); - for (int i = 0; i < node.getTransforms().size(); i++) { - if (i != 0) { - nodeCode.append(",\n"); - } - Transform transform = node.getTransforms().get(i); - if (transform instanceof Translate) { - Translate t = (Translate) transform; - nodeCode.append(indent + " " + storeTransform(t) + " = new Translate(" + t.getX() + "," - + t.getY() + "," + t.getZ() + ")"); - } else if (transform instanceof Scale) { - Scale s = (Scale) transform; - nodeCode.append(indent + " " + storeTransform(s) + " = new Scale(" + s.getX() + "," + s.getY() - + "," + s.getZ() + "," + s.getPivotX() + "," + s.getPivotY() + "," + s.getPivotZ() + ")"); - } else if (transform instanceof Rotate) { - Rotate r = (Rotate) transform; - nodeCode.append(indent + " " + storeTransform(r) + " = new Rotate(" + r.getAngle() + "," - + r.getPivotX() + "," + r.getPivotY() + "," + r.getPivotZ() + ","); - if (r.getAxis() == Rotate.X_AXIS) { - nodeCode.append("Rotate.X_AXIS"); - } else if (r.getAxis() == Rotate.Y_AXIS) { - nodeCode.append("Rotate.Y_AXIS"); - } else if (r.getAxis() == Rotate.Z_AXIS) { - nodeCode.append("Rotate.Z_AXIS"); - } - nodeCode.append(")"); - } else { - throw new UnsupportedOperationException("Unknown Transform Type: " + transform.getClass()); - } - - } - nodeCode.append("\n" + indent + ");\n"); - } - } - - private String storeTransform(Transform transform) { - String varName; - if (transform instanceof Translate) { - final int index = translateCount++; - varName = "TRANS_" + index; - Translate t = (Translate) transform; - writableVarMap.put(t.xProperty(), varName + ".xProperty()"); - writableVarMap.put(t.yProperty(), varName + ".yProperty()"); - writableVarMap.put(t.zProperty(), varName + ".zProperty()"); - } else if (transform instanceof Scale) { - final int index = scaleCount++; - varName = "SCALE_" + index; - Scale s = (Scale) transform; - writableVarMap.put(s.xProperty(), varName + ".xProperty()"); - writableVarMap.put(s.yProperty(), varName + ".yProperty()"); - writableVarMap.put(s.zProperty(), varName + ".zProperty()"); - writableVarMap.put(s.pivotXProperty(), varName + ".pivotXProperty()"); - writableVarMap.put(s.pivotYProperty(), varName + ".pivotYProperty()"); - writableVarMap.put(s.pivotZProperty(), varName + ".pivotZProperty()"); - } else if (transform instanceof Rotate) { - final int index = rotateCount++; - varName = "ROT_" + index; - Rotate r = (Rotate) transform; - writableVarMap.put(r.angleProperty(), varName + ".angleProperty()"); - } else { - throw new UnsupportedOperationException("Unknown Transform Type: " + transform.getClass()); - } - return varName; - } - - private String toCode(Color color) { - return color == null ? null - : "new Color(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," - + color.getOpacity() + ")"; - } - - private String toString(Image image) { - @SuppressWarnings("deprecation") - String url = image.getUrl(); - if (url.startsWith(baseUrl)) { - return "new Image(" + className + ".class.getResource(\"" + url.substring(baseUrl.length()) - + "\").toExternalForm())"; - } else { - return "new Image(\"" + url + "\")"; - } - } - - private String toString(Interpolator interpolator) { - // if (interpolator == Interpolator.DISCRETE || true) { - if (interpolator == Interpolator.DISCRETE) { - return "Interpolator.DISCRETE"; - } else if (interpolator == Interpolator.EASE_BOTH) { - return "Interpolator.EASE_BOTH"; - } else if (interpolator == Interpolator.EASE_IN) { - return "Interpolator.EASE_IN"; - } else if (interpolator == Interpolator.EASE_OUT) { - return "Interpolator.EASE_OUT"; - } else if (interpolator == Interpolator.LINEAR) { - return "Interpolator.LINEAR"; - } else if (interpolator instanceof SplineInterpolator) { - SplineInterpolator si = (SplineInterpolator) interpolator; - return "Interpolator.SPLINE(" + si.getX1() + "d," + si.getY1() + "d," + si.getX2() + "d," + si.getY2() - + "d)"; - } else if (interpolator instanceof NumberTangentInterpolator) { - NumberTangentInterpolator ti = (NumberTangentInterpolator) interpolator; - return "Interpolator.TANGENT(Duration.millis(" + TickCalculation.toMillis((long) ti.getInTicks()) + "d)," - + ti.getInValue() + "d,Duration.millis(" + TickCalculation.toMillis((long) ti.getInTicks()) + "d)," - + ti.getOutValue() + "d)"; - } else { - throw new UnsupportedOperationException("Unknown Interpolator type: " + interpolator.getClass()); - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalApp.java b/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalApp.java deleted file mode 100644 index ca7e19a..0000000 --- a/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalApp.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.height2normal; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; - -import javax.imageio.ImageIO; - -import com.javafx.experiments.jfx3dviewer.AutoScalingGroup; - -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.application.Application; -import javafx.beans.binding.ObjectBinding; -import javafx.beans.property.SimpleObjectProperty; -import javafx.embed.swing.SwingFXUtils; -import javafx.scene.Group; -import javafx.scene.PerspectiveCamera; -import javafx.scene.Scene; -import javafx.scene.SubScene; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.Label; -import javafx.scene.control.Separator; -import javafx.scene.control.Slider; -import javafx.scene.control.ToolBar; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.HBox; -import javafx.scene.layout.Priority; -import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.Box; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Translate; -import javafx.stage.FileChooser; -import javafx.stage.Stage; -import javafx.util.Duration; - -/** - * Gui Util App for converting Heights 2 Normals - */ -public class Height2NormalApp extends Application { - private class View3D { - private AutoScalingGroup autoScalingGroup = new AutoScalingGroup(2); - private final PerspectiveCamera camera = new PerspectiveCamera(true); - private final Rotate cameraLookXRotate = new Rotate(0, 0, 0, - 0, - Rotate.X_AXIS); - private final Rotate cameraLookZRotate = new Rotate(0, 0, 0, - 0, - Rotate.Z_AXIS); - private final Translate cameraPosition = new Translate(0, 0, - -7); - private final Rotate cameraXRotate = new Rotate(-40, 0, - 0, 0, - Rotate.X_AXIS); - private final Rotate cameraYRotate = new Rotate(-20, 0, - 0, 0, - Rotate.Y_AXIS); - private final Group root3D = new Group(); - - public SubScene create() { - SubScene scene = new SubScene(root3D, 512, 512, true, null); - scene.setFill(Color.ALICEBLUE); - - // CAMERA - camera.getTransforms() - .addAll(cameraXRotate, cameraYRotate, cameraPosition, - cameraLookXRotate, cameraLookZRotate); - camera.setNearClip(0.1); - camera.setFarClip(100); - scene.setCamera(camera); - root3D.getChildren() - .addAll(camera, autoScalingGroup); - - Box box = new Box(10, 0.11, 10); - - PhongMaterial material = new PhongMaterial(Color.DODGERBLUE); - material.bumpMapProperty() - .bind(normalImage); - box.setMaterial(material); - - autoScalingGroup.getChildren() - .add(box); - - Timeline timeline = new Timeline(new KeyFrame(Duration.ZERO, - new KeyValue(cameraYRotate.angleProperty(), - 0)), - new KeyFrame(Duration.seconds(10), - new KeyValue(cameraYRotate.angleProperty(), - 360))); - timeline.setCycleCount(Animation.INDEFINITE); - timeline.play(); - - return scene; - } - } - - public static void main(String[] args) { - launch(args); - } - - private File heightFile; - private SimpleObjectProperty heightImage = new SimpleObjectProperty<>(); - private SimpleObjectProperty normalImage = new SimpleObjectProperty<>(); - - private Stage stage; - - private Image testImage; - - public void open() { - FileChooser fileChooser = new FileChooser(); - heightFile = fileChooser.showOpenDialog(stage); - if (heightFile != null) { - try { - heightImage.set(new Image(heightFile.toURI() - .toURL() - .toExternalForm())); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } else { - heightImage.set(testImage); - } - } - - public void save() { - FileChooser fileChooser = new FileChooser(); - if (heightFile != null) { - String filePath = heightFile.getName(); - fileChooser.setInitialFileName(filePath.substring(0, - filePath.lastIndexOf('.')) - + "-normal-map.png"); - } else { - fileChooser.setInitialFileName("normal-map.png"); - } - File normalFile = fileChooser.showSaveDialog(stage); - if (normalFile != null) { - try { - ImageIO.write(SwingFXUtils.fromFXImage(normalImage.get(), null), - "png", normalFile); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public void start(Stage stage) throws Exception { - this.stage = stage; - - // load test image - // testImage = new Image(Height2NormalApp.class.getResource("javafx-heightmap.jpg").toExternalForm()); - testImage = new Image(Height2NormalApp.class.getResource("/com/javafx/experiments/jfx3dviewer/blue.jpg") - .toExternalForm()); - heightImage.set(testImage); - - // create toolbar - ToolBar toolBar = new ToolBar(); - Button openButton = new Button("Open..."); - openButton.setOnAction(event -> open()); - Button saveButton = new Button("Save..."); - saveButton.setOnAction(event -> save()); - final CheckBox invertCheckBox = new CheckBox("invert"); - final Slider scaleSlider = new Slider(1, 50, 2); - toolBar.getItems() - .addAll(openButton, saveButton, new Separator(), invertCheckBox, - new Separator(), new Label("Scale:"), scaleSlider); - - // bind creation of normal image - normalImage.bind(new ObjectBinding() { - { - bind(heightImage, invertCheckBox.selectedProperty(), - scaleSlider.valueProperty()); - } - - @Override - protected Image computeValue() { - return Height2NormalConverter.convertToNormals(heightImage.get(), - invertCheckBox.isSelected(), - scaleSlider.getValue()); - } - }); - - // build stage - VBox root = new VBox(); - HBox views = new HBox(); - VBox.setVgrow(views, Priority.ALWAYS); - root.getChildren() - .addAll(toolBar, views); - - ImageView srcImageView = new ImageView(); - srcImageView.setFitWidth(512); - srcImageView.setFitHeight(512); - srcImageView.imageProperty() - .bind(heightImage); - ImageView dstImageView = new ImageView(); - dstImageView.setFitWidth(512); - dstImageView.setFitHeight(512); - dstImageView.imageProperty() - .bind(normalImage); - views.getChildren() - .addAll(srcImageView, dstImageView, new View3D().create()); - - Scene scene = new Scene(root); - stage.setScene(scene); - stage.show(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalConverter.java b/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalConverter.java deleted file mode 100644 index a8c7d71..0000000 --- a/gui/src/main/java/com/javafx/experiments/height2normal/Height2NormalConverter.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.height2normal; - -import javafx.geometry.Point3D; -import javafx.scene.image.Image; -import javafx.scene.image.PixelFormat; -import javafx.scene.image.PixelReader; -import javafx.scene.image.WritableImage; - -/** - * Util class to convert height maps into normal maps - */ -public class Height2NormalConverter { - public static Image convertToNormals(Image heightMap, boolean invert, - double scale) { - final int w = (int) heightMap.getWidth(); - final int h = (int) heightMap.getHeight(); - final byte[] heightPixels = new byte[w * h * 4]; - final byte[] normalPixels = new byte[w * h * 4]; - // get pixels - final PixelReader reader = heightMap.getPixelReader(); - reader.getPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), - heightPixels, 0, w * 4); - if (invert) { - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - final int pixelIndex = (y * w * 4) + (x * 4); - heightPixels[pixelIndex] = (byte) (255 - - Byte.toUnsignedInt(heightPixels[pixelIndex])); - heightPixels[pixelIndex - + 1] = (byte) (255 - - Byte.toUnsignedInt(heightPixels[pixelIndex - + 1])); - heightPixels[pixelIndex - + 2] = (byte) (255 - - Byte.toUnsignedInt(heightPixels[pixelIndex - + 2])); - heightPixels[pixelIndex + 3] = heightPixels[pixelIndex + 3]; - } - } - } - // generate normal map - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - final int yAbove = Math.max(0, y - 1); - final int yBelow = Math.min(h - 1, y + 1); - final int xLeft = Math.max(0, x - 1); - final int xRight = Math.min(w - 1, x + 1); - final int pixelIndex = (y * w * 4) + (x * 4); - final int pixelAboveIndex = (yAbove * w * 4) + (x * 4); - final int pixelBelowIndex = (yBelow * w * 4) + (x * 4); - final int pixelLeftIndex = (y * w * 4) + (xLeft * 4); - final int pixelRightIndex = (y * w * 4) + (xRight * 4); - final int pixelAboveHeight = Byte.toUnsignedInt(heightPixels[pixelAboveIndex]); - final int pixelBelowHeight = Byte.toUnsignedInt(heightPixels[pixelBelowIndex]); - final int pixelLeftHeight = Byte.toUnsignedInt(heightPixels[pixelLeftIndex]); - final int pixelRightHeight = Byte.toUnsignedInt(heightPixels[pixelRightIndex]); - - Point3D pixelAbove = new Point3D(x, yAbove, pixelAboveHeight); - Point3D pixelBelow = new Point3D(x, yBelow, pixelBelowHeight); - Point3D pixelLeft = new Point3D(xLeft, y, pixelLeftHeight); - Point3D pixelRight = new Point3D(xRight, y, pixelRightHeight); - Point3D H = pixelLeft.subtract(pixelRight); - Point3D V = pixelAbove.subtract(pixelBelow); - Point3D normal = H.crossProduct(V); - // normalize normal - normal = new Point3D(normal.getX() / w, normal.getY() / h, - normal.getZ()); - // it seems there is lots of ways to calculate the Z element of normal map, 3 options here - // normalPixels[pixelIndex] = (byte)((normal.getZ()*128)+128); // Option 1 - normalPixels[pixelIndex] = (byte) (255 - - (normal.getZ() * scale)); // Option 2 - // normalPixels[pixelIndex] = (byte)255; // Option 3 - normalPixels[pixelIndex - + 1] = (byte) ((normal.getY() * 128) + 128); - normalPixels[pixelIndex - + 2] = (byte) ((normal.getX() * 128) + 128); - normalPixels[pixelIndex + 3] = (byte) 255; - } - } - // create output image - final WritableImage outImage = new WritableImage(w, h); - outImage.getPixelWriter() - .setPixels(0, 0, w, h, PixelFormat.getByteBgraInstance(), - normalPixels, 0, w * 4); - return outImage; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/Importer.java b/gui/src/main/java/com/javafx/experiments/importers/Importer.java deleted file mode 100644 index 0719b62..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/Importer.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import java.io.IOException; - -import javafx.animation.Timeline; -import javafx.scene.Group; - -public abstract class Importer { - /** - * Gets the 3D node that was loaded earlier through the load() call - * - * @return The loaded node - */ - public abstract Group getRoot(); - - /** - * Can be overridden to return a timeline animation for the 3D file - * - * @return A timeline animation. Null if there is no timeline animation. - */ - public Timeline getTimeline() { - return null; - } - - /** - * Tests if the given 3D file extension is supported (e.g. "ma", "ase", - * "obj", "fxml", "dae"). - * - * @param supportType - * The file extension (e.g. "ma", "ase", "obj", "fxml", "dae") - * @return True if the extension is of a supported type. False otherwise. - */ - public abstract boolean isSupported(String supportType); - - /** - * Loads the 3D file - * - * @param url - * The url of the 3D file to load - * @param asPolygonMesh - * When true load as a PolygonMesh if the loader supports. - * @throws IOException - * If issue loading file - */ - public abstract void load(String url, - boolean asPolygonMesh) throws IOException; -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/Importer3D.java b/gui/src/main/java/com/javafx/experiments/importers/Importer3D.java deleted file mode 100644 index d284423..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/Importer3D.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ServiceLoader; - -import javafx.animation.Timeline; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.util.Pair; - -/** - * Base Importer for all supported 3D file formats - */ -public final class Importer3D { - - /** - * Get array of extension filters for supported file formats. - * - * @return array of extension filters for supported file formats. - */ - public static String[] getSupportedFormatExtensionFilters() { - return new String[] { "*.ma", "*.ase", "*.obj", "*.fxml", "*.dae" }; - } - - /** - * Load a 3D file, always loaded as TriangleMesh. - * - * @param fileUrl - * The url of the 3D file to load - * @return The loaded Node which could be a MeshView or a Group - * @throws IOException - * if issue loading file - */ - public static Node load(String fileUrl) throws IOException { - return load(fileUrl, false); - } - - /** - * Load a 3D file. - * - * @param fileUrl - * The url of the 3D file to load - * @param asPolygonMesh - * When true load as a PolygonMesh if the loader supports - * @return The loaded Node which could be a MeshView or a Group - * @throws IOException - * if issue loading file - */ - public static Node load(String fileUrl, - boolean asPolygonMesh) throws IOException { - return loadIncludingAnimation(fileUrl, asPolygonMesh).getKey(); - } - - /** - * Load a 3D file. - * - * @param fileUrl - * The url of the 3D file to load - * @param asPolygonMesh - * When true load as a PolygonMesh if the loader supports - * @return The loaded Node which could be a MeshView or a Group and the - * Timeline animation - * @throws IOException - * if issue loading file - */ - public static Pair loadIncludingAnimation(String fileUrl, - boolean asPolygonMesh) throws IOException { - // get extension - final int dot = fileUrl.lastIndexOf('.'); - if (dot <= 0) { - throw new IOException("Unknown 3D file format, url missing extension [" - + fileUrl + "]"); - } - final String extension = fileUrl.substring(dot + 1, fileUrl.length()) - .toLowerCase(); - // Reference all the importer jars - ImporterFinder finder = new ImporterFinder(); - URLClassLoader classLoader = finder.addUrlToClassPath(); - - ServiceLoader servantLoader = ServiceLoader.load(Importer.class, - classLoader); - // Check if we have an implementation for this file type - Importer importer = null; - for (Importer plugin : servantLoader) { - if (plugin.isSupported(extension)) { - importer = plugin; - break; - } - } - - // Check well known loaders that might not be in a jar (ie. running from an IDE) - if ((importer == null) && (!extension.equals("fxml"))) { - String[] names = { "com.javafx.experiments.importers.dae.DaeImporter", - "com.javafx.experiments.importers.max.MaxLoader", - "com.javafx.experiments.importers.maya.MayaImporter", - "com.javafx.experiments.importers.obj.ObjOrPolyObjImporter", }; - boolean fail = true; - for (String name : names) { - try { - Class clazz = Class.forName(name); - Object obj = clazz.newInstance(); - if (obj instanceof Importer) { - Importer plugin = (Importer) obj; - if (plugin.isSupported(extension)) { - importer = plugin; - fail = false; - break; - } - } - } catch (ClassNotFoundException | InstantiationException - | IllegalAccessException e) { - // FAIL SILENTLY - } - } - if (fail) { - throw new IOException("Unknown 3D file format [" + extension - + "]"); - } - } - - if (extension.equals("fxml")) { - final Object fxmlRoot = FXMLLoader.load(new URL(fileUrl)); - if (fxmlRoot instanceof Node) { - return new Pair<>((Node) fxmlRoot, null); - } else if (fxmlRoot instanceof TriangleMesh) { - return new Pair<>(new MeshView((TriangleMesh) fxmlRoot), null); - } - throw new IOException("Unknown object in FXML file [" - + fxmlRoot.getClass() - .getName() - + "]"); - } else { - importer.load(fileUrl, asPolygonMesh); - return new Pair<>(importer.getRoot(), importer.getTimeline()); - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/ImporterFinder.java b/gui/src/main/java/com/javafx/experiments/importers/ImporterFinder.java deleted file mode 100644 index d0bc415..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/ImporterFinder.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; - -public class ImporterFinder { - - public URLClassLoader addUrlToClassPath() { - final Class referenceClass = ImporterFinder.class; - final URL url = referenceClass.getProtectionDomain() - .getCodeSource() - .getLocation(); - - File libDir = null; - try { - File currentDir = new File(url.toURI()).getParentFile(); - libDir = new File(currentDir, "lib"); - } catch (URISyntaxException ue) { - ue.printStackTrace(); - throw new RuntimeException("Could not import library. Failed to determine library location. URL = " - + url.getPath()); - } - File[] files = libDir.listFiles(); - final List urlList = new ArrayList<>(); - if (files != null) { - for (File file : files) { - try { - urlList.add(file.toURI() - .toURL()); - } catch (MalformedURLException me) { - me.printStackTrace(); - } - } - } - URLClassLoader cl = new URLClassLoader(urlList.toArray(new URL[0]), - this.getClass() - .getClassLoader()); - return cl; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/Optimizer.java b/gui/src/main/java/com/javafx/experiments/importers/Optimizer.java deleted file mode 100644 index 3959bca..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/Optimizer.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javafx.animation.Interpolator; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.beans.property.Property; -import javafx.beans.value.WritableValue; -import javafx.collections.FXCollections; -import javafx.collections.ObservableFloatArray; -import javafx.collections.ObservableIntegerArray; -import javafx.collections.ObservableList; -import javafx.collections.transformation.SortedList; -import javafx.geometry.Point2D; -import javafx.geometry.Point3D; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Transform; - -/** - * Optimizer to take 3D model and timeline loaded by one of the importers and do - * as much optimization on the scene graph that was create as we can while still - * being able to play the given animation. - */ -public class Optimizer { - - private static class KeyFrameComparator implements Comparator { - - public KeyFrameComparator() { - } - - @Override - public int compare(KeyFrame o1, KeyFrame o2) { - // int compareTo = o1.getTime().compareTo(o2.getTime()); - // if (compareTo == 0 && o1 != o2) { - // System.err.println("those two KeyFrames are equal: o1 = " + o1.getTime() + " and o2 = " + o2.getTime()); - // } - return o1.getTime() - .compareTo(o2.getTime()); - } - } - - private static class KeyInfo { - boolean first; - KeyFrame keyFrame; - KeyValue keyValue; - - public KeyInfo(KeyFrame keyFrame, KeyValue keyValue, boolean first) { - this.keyFrame = keyFrame; - this.keyValue = keyValue; - this.first = first; - } - } - - private static class MapOfLists extends HashMap> { - - private static final long serialVersionUID = 1L; - - public void add(K key, V value) { - List p = get(key); - if (p == null) { - p = new ArrayList<>(); - put(key, p); - } - p.add(value); - } - } - - private Set bound = new HashSet<>(); - private boolean convertToDiscrete = true; - private List emptyParents = new ArrayList<>(); - - private List meshViews = new ArrayList<>(); - - private Node root; - - private Timeline timeline; - - private int trRemoved, trTotal, groupsTotal, trCandidate, - trEmpty; - - public Optimizer(Timeline timeline, Node root) { - this(timeline, root, false); - } - - public Optimizer(Timeline timeline, Node root, boolean convertToDiscrete) { - this.timeline = timeline; - this.root = root; - this.convertToDiscrete = convertToDiscrete; - } - - public void optimize() { - trRemoved = 0; - trTotal = 0; - trCandidate = 0; - trEmpty = 0; - groupsTotal = 0; - emptyParents.clear(); - - parseTimeline(); - optimize(root); - removeEmptyGroups(); - optimizeMeshes(); - - System.out.printf("removed %d (%.2f%%) out of total %d transforms\n", - trRemoved, 100d * trRemoved / trTotal, trTotal); - System.out.printf("there are %d more multiplications that can be done of matrices that never change\n", - trCandidate); - System.out.printf("there are %d (%.2f%%) out of total %d groups with no transforms in them\n", - trEmpty, 100d * trEmpty / groupsTotal, groupsTotal); - } - - private void optimize(Node node) { - ObservableList transforms = node.getTransforms(); - Iterator iterator = transforms.iterator(); - boolean prevIsStatic = false; - while (iterator.hasNext()) { - Transform transform = iterator.next(); - trTotal++; - if (transform.isIdentity()) { - if (timeline == null || !bound.contains(transform)) { - iterator.remove(); - trRemoved++; - } - } else { - if (timeline == null || !bound.contains(transform)) { - if (prevIsStatic) { - trCandidate++; - } - prevIsStatic = true; - } else { - prevIsStatic = false; - } - } - } - if (node instanceof Parent) { - groupsTotal++; - Parent p = (Parent) node; - for (Node n : p.getChildrenUnmodifiable()) { - optimize(n); - } - if (transforms.isEmpty()) { - Parent parent = p.getParent(); - if (parent instanceof Group) { - trEmpty++; - // System.out.println("Empty group = " + node.getId()); - emptyParents.add(p); - } else { - // System.err.println("parent is not group = " + parent); - } - } - } - if (node instanceof MeshView) { - meshViews.add((MeshView) node); - } - } - - private void optimizeFaces() { - int total = 0, sameIndexes = 0, samePoints = 0, smallArea = 0; - ObservableIntegerArray newFaces = FXCollections.observableIntegerArray(); - ObservableIntegerArray newFaceSmoothingGroups = FXCollections.observableIntegerArray(); - for (MeshView meshView : meshViews) { - TriangleMesh mesh = (TriangleMesh) meshView.getMesh(); - ObservableIntegerArray faces = mesh.getFaces(); - ObservableIntegerArray faceSmoothingGroups = mesh.getFaceSmoothingGroups(); - ObservableFloatArray points = mesh.getPoints(); - newFaces.clear(); - newFaces.ensureCapacity(faces.size()); - newFaceSmoothingGroups.clear(); - newFaceSmoothingGroups.ensureCapacity(faceSmoothingGroups.size()); - int pointElementSize = mesh.getPointElementSize(); - int faceElementSize = mesh.getFaceElementSize(); - for (int i = 0; i < faces.size(); i += faceElementSize) { - total++; - int i1 = faces.get(i) * pointElementSize; - int i2 = faces.get(i + 2) * pointElementSize; - int i3 = faces.get(i + 4) * pointElementSize; - if (i1 == i2 || i1 == i3 || i2 == i3) { - sameIndexes++; - continue; - } - Point3D p1 = new Point3D(points.get(i1), points.get(i1 + 1), - points.get(i1 + 2)); - Point3D p2 = new Point3D(points.get(i2), points.get(i2 + 1), - points.get(i2 + 2)); - Point3D p3 = new Point3D(points.get(i3), points.get(i3 + 1), - points.get(i3 + 2)); - if (p1.equals(p2) || p1.equals(p3) || p2.equals(p3)) { - samePoints++; - continue; - } - double a = p1.distance(p2); - double b = p2.distance(p3); - double c = p3.distance(p1); - double p = (a + b + c) / 2; - double sqarea = p * (p - a) * (p - b) * (p - c); - - final float DEAD_FACE = 1.f / 1024 / 1024 / 1024 / 1024; // taken from MeshNormal code - - if (sqarea < DEAD_FACE) { - smallArea++; - // System.out.printf("a = %e, b = %e, c = %e, sqarea = %e\n" - // + "p1 = %s\np2 = %s\np3 = %s\n", a, b, c, sqarea, p1.toString(), p2.toString(), p3.toString()); - continue; - } - newFaces.addAll(faces, i, faceElementSize); - int fIndex = i / faceElementSize; - if (fIndex < faceSmoothingGroups.size()) { - newFaceSmoothingGroups.addAll(faceSmoothingGroups.get(fIndex)); - } - } - faces.setAll(newFaces); - faceSmoothingGroups.setAll(newFaceSmoothingGroups); - faces.trimToSize(); - faceSmoothingGroups.trimToSize(); - } - int badTotal = sameIndexes + samePoints + smallArea; - System.out.printf("Removed %d (%.2f%%) faces with same point indexes, " - + "%d (%.2f%%) faces with same points, " - + "%d (%.2f%%) faces with small area. " - + "Total %d (%.2f%%) bad faces out of %d total.\n", - sameIndexes, 100d * sameIndexes / total, samePoints, - 100d * samePoints / total, smallArea, - 100d * smallArea / total, badTotal, - 100d * badTotal / total, total); - } - - private void optimizeMeshes() { - optimizePoints(); - optimizeTexCoords(); - optimizeFaces(); - } - - private void optimizePoints() { - int total = 0, duplicates = 0, check = 0; - - Map pp = new HashMap<>(); - ObservableIntegerArray reindex = FXCollections.observableIntegerArray(); - ObservableFloatArray newPoints = FXCollections.observableFloatArray(); - - for (MeshView meshView : meshViews) { - TriangleMesh mesh = (TriangleMesh) meshView.getMesh(); - ObservableFloatArray points = mesh.getPoints(); - int pointElementSize = mesh.getPointElementSize(); - int os = points.size() / pointElementSize; - - pp.clear(); - newPoints.clear(); - newPoints.ensureCapacity(points.size()); - reindex.clear(); - reindex.resize(os); - - for (int i = 0, oi = 0, ni = 0; i < points.size(); i += pointElementSize, oi++) { - float x = points.get(i); - float y = points.get(i + 1); - float z = points.get(i + 2); - Point3D p = new Point3D(x, y, z); - Integer index = pp.get(p); - if (index == null) { - pp.put(p, ni); - reindex.set(oi, ni); - newPoints.addAll(x, y, z); - ni++; - } else { - reindex.set(oi, index); - } - } - - int ns = newPoints.size() / pointElementSize; - - int d = os - ns; - duplicates += d; - total += os; - - points.setAll(newPoints); - points.trimToSize(); - - ObservableIntegerArray faces = mesh.getFaces(); - for (int i = 0; i < faces.size(); i += 2) { - faces.set(i, reindex.get(faces.get(i))); - } - - // System.out.printf("There are %d (%.2f%%) duplicate points out of %d total for mesh '%s'.\n", - // d, 100d * d / os, os, meshView.getId()); - - check += mesh.getPoints() - .size() - / pointElementSize; - } - System.out.printf("There are %d (%.2f%%) duplicate points out of %d total.\n", - duplicates, 100d * duplicates / total, total); - System.out.printf("Now we have %d points.\n", check); - } - - private void optimizeTexCoords() { - int total = 0, duplicates = 0, check = 0; - - Map pp = new HashMap<>(); - ObservableIntegerArray reindex = FXCollections.observableIntegerArray(); - ObservableFloatArray newTexCoords = FXCollections.observableFloatArray(); - - for (MeshView meshView : meshViews) { - TriangleMesh mesh = (TriangleMesh) meshView.getMesh(); - ObservableFloatArray texcoords = mesh.getTexCoords(); - int texcoordElementSize = mesh.getTexCoordElementSize(); - int os = texcoords.size() / texcoordElementSize; - - pp.clear(); - newTexCoords.clear(); - newTexCoords.ensureCapacity(texcoords.size()); - reindex.clear(); - reindex.resize(os); - - for (int i = 0, oi = 0, ni = 0; i < texcoords.size(); i += texcoordElementSize, oi++) { - float x = texcoords.get(i); - float y = texcoords.get(i + 1); - Point2D p = new Point2D(x, y); - Integer index = pp.get(p); - if (index == null) { - pp.put(p, ni); - reindex.set(oi, ni); - newTexCoords.addAll(x, y); - ni++; - } else { - reindex.set(oi, index); - } - } - - int ns = newTexCoords.size() / texcoordElementSize; - - int d = os - ns; - duplicates += d; - total += os; - - texcoords.setAll(newTexCoords); - texcoords.trimToSize(); - - ObservableIntegerArray faces = mesh.getFaces(); - for (int i = 1; i < faces.size(); i += 2) { - faces.set(i, reindex.get(faces.get(i))); - } - - // System.out.printf("There are %d (%.2f%%) duplicate texcoords out of %d total for mesh '%s'.\n", - // d, 100d * d / os, os, meshView.getId()); - - check += mesh.getTexCoords() - .size() - / texcoordElementSize; - } - System.out.printf("There are %d (%.2f%%) duplicate texcoords out of %d total.\n", - duplicates, 100d * duplicates / total, total); - System.out.printf("Now we have %d texcoords.\n", check); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void parseTimeline() { - bound.clear(); - if (timeline == null) { - return; - } - // cleanUpRepeatingFramesAndValues(); // we don't need it usually as timeline is initially correct - SortedList sortedKeyFrames = timeline.getKeyFrames() - .sorted(new KeyFrameComparator()); - MapOfLists toRemove = new MapOfLists<>(); - Map prevValues = new HashMap<>(); - Map prevPrevValues = new HashMap<>(); - int kvTotal = 0; - for (KeyFrame keyFrame : sortedKeyFrames) { - for (KeyValue keyValue : keyFrame.getValues()) { - WritableValue target = keyValue.getTarget(); - KeyInfo prev = prevValues.get(target); - kvTotal++; - if (prev != null && prev.keyValue.getEndValue() - .equals(keyValue.getEndValue())) { - // if (prev != null && (prev.keyValue.equals(keyValue) || (prev.first && prev.keyValue.getEndValue().equals(keyValue.getEndValue())))) { - KeyInfo prevPrev = prevPrevValues.get(target); - if ((prevPrev != null && prevPrev.keyValue.getEndValue() - .equals(keyValue.getEndValue())) - || (prev.first && target.getValue() - .equals(prev.keyValue.getEndValue()))) { - // All prevPrev, prev and current match, so prev can be removed - // or prev is first and its value equals to the property existing value, so prev can be removed - toRemove.add(prev.keyFrame, prev.keyValue); - } else { - prevPrevValues.put(target, prev); - // KeyInfo oldKeyInfo = prevPrevValues.put(target, prev); - // if (oldKeyInfo != null && oldKeyInfo.keyFrame.getTime().equals(prev.keyFrame.getTime())) { - // System.err.println("prevPrev replaced more than once per keyFrame on " + target + "\n" - // + "old = " + oldKeyInfo.keyFrame.getTime() + ", " + oldKeyInfo.keyValue + "\n" - // + "new = " + prev.keyFrame.getTime() + ", " + prev.keyValue - // ); - // } - } - } - KeyInfo oldPrev = prevValues.put(target, - new KeyInfo(keyFrame, keyValue, - prev == null)); - if (oldPrev != null) { - prevPrevValues.put(target, oldPrev); - } - } - } - // Deal with ending keyValues - for (WritableValue target : prevValues.keySet()) { - KeyInfo prev = prevValues.get(target); - KeyInfo prevPrev = prevPrevValues.get(target); - if (prevPrev != null && prevPrev.keyValue.getEndValue() - .equals(prev.keyValue.getEndValue())) { - // prevPrev and prev match, so prev can be removed - toRemove.add(prev.keyFrame, prev.keyValue); - } - } - int kvRemoved = 0; - int kfRemoved = 0, kfTotal = timeline.getKeyFrames() - .size(), - kfSimplified = 0, kfNotRemoved = 0; - // Removing unnecessary KeyValues and KeyFrames - List newKeyValues = new ArrayList<>(); - for (int i = 0; i < timeline.getKeyFrames() - .size(); i++) { - KeyFrame keyFrame = timeline.getKeyFrames() - .get(i); - List keyValuesToRemove = toRemove.get(keyFrame); - if (keyValuesToRemove != null) { - newKeyValues.clear(); - for (KeyValue keyValue : keyFrame.getValues()) { - if (keyValuesToRemove.remove(keyValue)) { - kvRemoved++; - } else { - if (convertToDiscrete) { - newKeyValues.add(new KeyValue((WritableValue) keyValue.getTarget(), - keyValue.getEndValue(), - Interpolator.DISCRETE)); - } else { - newKeyValues.add(keyValue); - } - } - } - } else if (convertToDiscrete) { - newKeyValues.clear(); - for (KeyValue keyValue : keyFrame.getValues()) { - newKeyValues.add(new KeyValue((WritableValue) keyValue.getTarget(), - keyValue.getEndValue(), - Interpolator.DISCRETE)); - } - } - if (keyValuesToRemove != null || convertToDiscrete) { - if (newKeyValues.isEmpty()) { - if (keyFrame.getOnFinished() == null) { - if (keyFrame.getName() != null) { - System.err.println("Removed KeyFrame with name = " - + keyFrame.getName()); - } - timeline.getKeyFrames() - .remove(i); - i--; - kfRemoved++; - continue; // for i - } else { - kfNotRemoved++; - } - } else { - keyFrame = new KeyFrame(keyFrame.getTime(), - keyFrame.getName(), - keyFrame.getOnFinished(), - newKeyValues); - timeline.getKeyFrames() - .set(i, keyFrame); - kfSimplified++; - } - } - // collecting bound targets - for (KeyValue keyValue : keyFrame.getValues()) { - WritableValue target = keyValue.getTarget(); - if (target instanceof Property) { - Property p = (Property) target; - Object bean = p.getBean(); - if (bean instanceof Transform) { - bound.add((Transform) bean); - } else { - throw new UnsupportedOperationException("Bean is not transform, bean = " - + bean); - } - } else { - throw new UnsupportedOperationException("WritableValue is not property, can't identify what it changes, target = " - + target); - } - } - } - // System.out.println("bound.size() = " + bound.size()); - System.out.printf("Removed %d (%.2f%%) repeating KeyValues out of total %d.\n", - kvRemoved, 100d * kvRemoved / kvTotal, kvTotal); - System.out.printf("Removed %d (%.2f%%) and simplified %d (%.2f%%) KeyFrames out of total %d. %d (%.2f%%) were not removed due to event handler attached.\n", - kfRemoved, 100d * kfRemoved / kfTotal, kfSimplified, - 100d * kfSimplified / kfTotal, kfTotal, kfNotRemoved, - 100d * kfNotRemoved / kfTotal); - int check = 0; - for (KeyFrame keyFrame : timeline.getKeyFrames()) { - check += keyFrame.getValues() - .size(); - // for (KeyValue keyValue : keyFrame.getValues()) { - // if (keyValue.getInterpolator() != Interpolator.DISCRETE) { - // throw new IllegalStateException(); - // } - // } - } - System.out.printf("Now there are %d KeyValues and %d KeyFrames.\n", - check, timeline.getKeyFrames() - .size()); - } - - private void removeEmptyGroups() { - for (Parent p : emptyParents) { - Parent parent = p.getParent(); - Group g = (Group) parent; - g.getChildren() - .addAll(p.getChildrenUnmodifiable()); - g.getChildren() - .remove(p); - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/SmoothingGroups.java b/gui/src/main/java/com/javafx/experiments/importers/SmoothingGroups.java deleted file mode 100644 index 207acbf..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/SmoothingGroups.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Queue; - -import com.javafx.experiments.utils3d.geom.Vec3f; - -import javafx.scene.shape.TriangleMesh; - -/** Util for converting Normals to Smoothing Groups */ -public class SmoothingGroups { - private class Edge { - int from, to; - int fromNormal, toNormal; - - public Edge(int from, int to, int fromNormal, int toNormal) { - this.from = Math.min(from, to); - this.to = Math.max(from, to); - this.fromNormal = Math.min(fromNormal, toNormal); - this.toNormal = Math.max(fromNormal, toNormal); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Edge other = (Edge) obj; - if (this.from != other.from) { - return false; - } - if (this.to != other.to) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 41 * hash + this.from; - hash = 41 * hash + this.to; - return hash; - } - - public boolean isSmooth(Edge edge) { - boolean smooth = (isNormalsEqual(getNormal(fromNormal), - getNormal(edge.fromNormal)) - && isNormalsEqual(getNormal(toNormal), - getNormal(edge.toNormal))) - || (isNormalsEqual(getNormal(fromNormal), - getNormal(edge.toNormal)) - && isNormalsEqual(getNormal(toNormal), - getNormal(edge.fromNormal))); - return smooth; - } - } - - private static final float normalAngle = 0.9994f; // cos(2) - - /** - * Calculates smoothing groups for data formatted in PolygonMesh style - * - * @param faces - * An array of faces, where each face consists of an array of - * vertex and uv indices - * @param faceNormals - * An array of face normals, where each face normal consists of - * an array of normal indices - * @param normals - * The array of normals - * @return An array of smooth groups, where the length of the array is the - * number of faces - */ - public static int[] calcSmoothGroups(int[][] faces, int[][] faceNormals, - float[] normals) { - SmoothingGroups smoothGroups = new SmoothingGroups(faces, faceNormals, - normals); - return smoothGroups.calcSmoothGroups(); - } - - /** - * Calculates smoothing groups for data formatted in TriangleMesh style - * - * @param flatFaces - * An array of faces, where each triangle face is represented by - * 6 (vertex and uv) indices - * @param flatFaceNormals - * An array of face normals, where each triangle face is - * represented by 3 normal indices - * @param normals - * The array of normals - * @return An array of smooth groups, where the length of the array is the - * number of faces - */ - public static int[] calcSmoothGroups(TriangleMesh mesh, int[] flatFaces, - int[] flatFaceNormals, - float[] normals) { - int faceElementSize = mesh.getFaceElementSize(); - int[][] faces = new int[flatFaces.length - / faceElementSize][faceElementSize]; - for (int f = 0; f < faces.length; f++) { - for (int e = 0; e < faceElementSize; e++) { - faces[f][e] = flatFaces[f * faceElementSize + e]; - } - } - int pointElementSize = mesh.getPointElementSize(); - int[][] faceNormals = new int[flatFaceNormals.length - / pointElementSize][pointElementSize]; - for (int f = 0; f < faceNormals.length; f++) { - for (int e = 0; e < pointElementSize; e++) { - faceNormals[f][e] = flatFaceNormals[f * pointElementSize + e]; - } - } - SmoothingGroups smoothGroups = new SmoothingGroups(faces, faceNormals, - normals); - return smoothGroups.calcSmoothGroups(); - } - - private static boolean isNormalsEqual(Vec3f n1, Vec3f n2) { - if (n1.x == 1.0e20f || n1.y == 1.0e20f || n1.z == 1.0e20f - || n2.x == 1.0e20f || n2.y == 1.0e20f || n2.z == 1.0e20f) { - //System.out.println("unlocked normal found, skipping"); - return false; - } - Vec3f myN1 = new Vec3f(n1); - myN1.normalize(); - Vec3f myN2 = new Vec3f(n2); - myN2.normalize(); - return myN1.dot(myN2) >= normalAngle; - } - - private Edge[][] faceEdges; - - private int[][] faceNormals; - - private int[][] faces; - - private float[] normals; - - private Queue q; - - private BitSet visited, notVisited; - - public SmoothingGroups(int faces[][], int[][] faceNormals, - float[] normals) { - this.faces = faces; - this.faceNormals = faceNormals; - this.normals = normals; - visited = new BitSet(faces.length); - notVisited = new BitSet(faces.length); - notVisited.set(0, faces.length, true); - q = new LinkedList(); - } - - Vec3f getNormal(int index) { - return new Vec3f(normals[index * 3], normals[index * 3 + 1], - normals[index * 3 + 2]); - } - - private List> calcConnComponents(Map> smoothEdges) { - //System.out.println("smoothEdges = " + smoothEdges); - List> groups = new ArrayList>(); - while (hasNextConnectedComponent()) { - List smoothGroup = getNextConnectedComponent(smoothEdges); - groups.add(smoothGroup); - } - return groups; - } - - private int[] calcSmoothGroups() { - computeFaceEdges(); - - // edge -> [faces] - Map> adjacentFaces = getAdjacentFaces(); - - // smooth edge -> [faces] - Map> smoothEdges = getSmoothEdges(adjacentFaces); - - //System.out.println("smoothEdges = " + smoothEdges); - List> groups = calcConnComponents(smoothEdges); - - return generateSmGroups(groups); - } - - private void computeFaceEdges() { - faceEdges = new Edge[faces.length][]; - for (int f = 0; f < faces.length; f++) { - int[] face = faces[f]; - int[] faceNormal = faceNormals[f]; - int n = face.length / 2; - faceEdges[f] = new Edge[n]; - int from = face[(n - 1) * 2]; - int fromNormal = faceNormal[n - 1]; - for (int i = 0; i < n; i++) { - int to = face[i * 2]; - int toNormal = faceNormal[i]; - Edge edge = new Edge(from, to, fromNormal, toNormal); - faceEdges[f][i] = edge; - from = to; - fromNormal = toNormal; - } - } - } - - private int[] generateSmGroups(List> groups) { - int[] smGroups = new int[faceNormals.length]; - int curGroup = 0; - for (int i = 0; i < groups.size(); i++) { - List list = groups.get(i); - if (list.size() == 1) { - smGroups[list.get(0)] = 0; - } else { - for (int j = 0; j < list.size(); j++) { - Integer faceIndex = list.get(j); - smGroups[faceIndex] = 1 << curGroup; - } - if (curGroup++ == 31) { - curGroup = 0; - } - } - } - return smGroups; - } - - private Map> getAdjacentFaces() { - Map> adjacentFaces = new HashMap>(); - for (int f = 0; f < faceEdges.length; f++) { - for (Edge edge : faceEdges[f]) { - if (!adjacentFaces.containsKey(edge)) { - adjacentFaces.put(edge, new ArrayList()); - } - adjacentFaces.get(edge) - .add(f); - } - } - for (Iterator>> it = adjacentFaces.entrySet() - .iterator(); it.hasNext();) { - Map.Entry> e = it.next(); - if (e.getValue() - .size() != 2) { - // just skip them - it.remove(); - } - } - return adjacentFaces; - } - - // edge -> [faces] - private List getNextConnectedComponent(Map> adjacentFaces) { - int index = notVisited.previousSetBit(faces.length - 1); - q.add(index); - visited.set(index); - notVisited.set(index, false); - List res = new ArrayList(); - while (!q.isEmpty()) { - Integer faceIndex = q.remove(); - res.add(faceIndex); - for (Edge edge : faceEdges[faceIndex]) { - List adjFaces = adjacentFaces.get(edge); - if (adjFaces == null) { - continue; - } - Integer adjFaceIndex = adjFaces.get(adjFaces.get(0) - .equals(faceIndex) ? 1 - : 0); - if (!visited.get(adjFaceIndex)) { - q.add(adjFaceIndex); - visited.set(adjFaceIndex); - notVisited.set(adjFaceIndex, false); - } - } - } - return res; - } - - private Map> getSmoothEdges(Map> adjacentFaces) { - Map> smoothEdges = new HashMap>(); - - for (int face = 0; face < faceEdges.length; face++) { - for (Edge edge : faceEdges[face]) { - List adjFaces = adjacentFaces.get(edge); - if (adjFaces == null || adjFaces.size() != 2) { - // could happen when we skip edges! - continue; - } - int adjFace = adjFaces.get(adjFaces.get(0) == face ? 1 : 0); - Edge[] adjFaceEdges = faceEdges[adjFace]; - int adjEdgeInd = Arrays.asList(adjFaceEdges) - .indexOf(edge); - if (adjEdgeInd == -1) { - System.out.println("Can't find edge " + edge + " in face " - + adjFace); - System.out.println(Arrays.asList(adjFaceEdges)); - continue; - } - Edge adjEdge = adjFaceEdges[adjEdgeInd]; - - if (edge.isSmooth(adjEdge)) { - if (!smoothEdges.containsKey(edge)) { - smoothEdges.put(edge, adjFaces); - } - } - } - } - return smoothEdges; - } - - private boolean hasNextConnectedComponent() { - return !notVisited.isEmpty(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/Validator.java b/gui/src/main/java/com/javafx/experiments/importers/Validator.java deleted file mode 100644 index 9c21fdc..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/Validator.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers; - -import javafx.collections.ObservableIntegerArray; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.shape.Mesh; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; - -/** - * Mesh data validator - */ -public class Validator { - - public void validate(Mesh mesh) { - if (!(mesh instanceof TriangleMesh)) { - throw new AssertionError("Mesh is not TriangleMesh: " - + mesh.getClass() + ", mesh = " + mesh); - } - TriangleMesh tMesh = (TriangleMesh) mesh; - int numPoints = tMesh.getPoints() - .size() - / tMesh.getPointElementSize(); - int numTexCoords = tMesh.getTexCoords() - .size() - / tMesh.getTexCoordElementSize(); - int numFaces = tMesh.getFaces() - .size() - / tMesh.getFaceElementSize(); - if (numPoints == 0 - || numPoints * tMesh.getPointElementSize() != tMesh.getPoints() - .size()) { - throw new AssertionError("Points array size is not correct: " - + tMesh.getPoints() - .size()); - } - if (numTexCoords == 0 - || numTexCoords - * tMesh.getTexCoordElementSize() != tMesh.getTexCoords() - .size()) { - throw new AssertionError("TexCoords array size is not correct: " - + tMesh.getPoints() - .size()); - } - if (numFaces == 0 - || numFaces * tMesh.getFaceElementSize() != tMesh.getFaces() - .size()) { - throw new AssertionError("Faces array size is not correct: " - + tMesh.getPoints() - .size()); - } - if (numFaces != tMesh.getFaceSmoothingGroups() - .size() - && tMesh.getFaceSmoothingGroups() - .size() > 0) { - throw new AssertionError("FaceSmoothingGroups array size is not correct: " - + tMesh.getPoints() - .size() - + ", numFaces = " + numFaces); - } - ObservableIntegerArray faces = tMesh.getFaces(); - for (int i = 0; i < faces.size(); i += 2) { - int pIndex = faces.get(i); - if (pIndex < 0 || pIndex > numPoints) { - throw new AssertionError("Incorrect point index: " + pIndex - + ", numPoints = " + numPoints); - } - int tcIndex = faces.get(i + 1); - if (tcIndex < 0 || tcIndex > numTexCoords) { - throw new AssertionError("Incorrect texCoord index: " + tcIndex - + ", numTexCoords = " + numTexCoords); - } - } - // System.out.println("Validation successfull of " + mesh); - } - - public void validate(Node node) { - if (node instanceof MeshView) { - MeshView meshView = (MeshView) node; - validate(meshView.getMesh()); - } else if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - validate(child); - } - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/dae/DaeImporter.java b/gui/src/main/java/com/javafx/experiments/importers/dae/DaeImporter.java deleted file mode 100644 index bef2bbc..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/dae/DaeImporter.java +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.dae; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import com.javafx.experiments.importers.Importer; -import com.javafx.experiments.shape3d.PolygonMesh; -import com.javafx.experiments.shape3d.PolygonMeshView; - -import javafx.geometry.Point3D; -import javafx.scene.Camera; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.PerspectiveCamera; -import javafx.scene.Scene; -import javafx.scene.paint.Color; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Affine; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Transform; -import javafx.scene.transform.Translate; - -/** - * Loader for ".dae" 3D files - * - * Notes: - * - * - Assume Y is up for now - Assume 1 Unit = 1 FX Unit - */ -public class DaeImporter extends Importer { - /** So far a node can be one of camera, geometry or group */ - private static final class DaeNode { - private Group group; - private final String id; - private Camera instance_camera; - private Object instance_geometry; - private final String name; - - private DaeNode(String id, String name) { - this.id = id; - this.name = name; - } - - public Group getGroup() { - if (group == null) { - group = new Group(); - } - return group; - } - - public boolean isCamera() { - return instance_camera != null; - } - - public boolean isMesh() { - return instance_geometry != null; - } - - @Override - public String toString() { - return "DaeNode{" + "id='" + id + '\'' + ", name='" + name + '\'' - + ", instance_camera=" + instance_camera - + ", instance_geometry=" + instance_geometry + ", group=" - + group + '}'; - } - } - - private class DaeSaxParser extends DefaultHandler { - private String authoringTool; - private StringBuilder charBuf; - private Map currentId = new HashMap<>(); - private List currentTransforms; - private Map floatArrays = new HashMap<>(); - private Map inputs = new HashMap<>(); - private LinkedList nodes = new LinkedList<>(); - private List pLists = new ArrayList<>(); - private State state = State.UNKNOWN; - private int[] vCounts; - private Double xfov, yfov, znear, zfar, aspect_ratio; - - @Override - public void characters(char[] ch, int start, - int length) throws SAXException { - charBuf.append(ch, start, length); - } - - @Override - public void endElement(String uri, String localName, - String qName) throws SAXException { - switch (state(qName)) { - case node: - DaeNode thisNode = nodes.pop(); - if (thisNode.isCamera()) { // IS CAMERA - thisNode.instance_camera.setId(thisNode.name); - thisNode.instance_camera.getTransforms() - .addAll(currentTransforms); - nodes.peek() - .getGroup() - .getChildren() - .add(thisNode.instance_camera); - } else if (thisNode.isMesh()) { // IS MESH VIEW - Node meshView; - if (thisNode.instance_geometry instanceof PolygonMesh) { - meshView = new PolygonMeshView((PolygonMesh) thisNode.instance_geometry); - } else { - meshView = new MeshView((TriangleMesh) thisNode.instance_geometry); - } - meshView.setId(thisNode.name); - meshView.getTransforms() - .addAll(currentTransforms); - nodes.peek() - .getGroup() - .getChildren() - .add(meshView); - } else { // IS GROUP - Group group = thisNode.getGroup(); - group.setId(thisNode.name); - group.getTransforms() - .addAll(currentTransforms); - nodes.peek() - .getGroup() - .getChildren() - .add(group); - } - break; - case aspect_ratio: - aspect_ratio = Double.parseDouble(charBuf.toString() - .trim()); - // workaround for Cheetah3D which seems to have it backwards - if ("Cheetah3D".equals(authoringTool)) { - aspect_ratio = 1 / aspect_ratio; - } - break; - case xfov: - yfov = Double.parseDouble(charBuf.toString() - .trim()); - break; - case yfov: - yfov = Double.parseDouble(charBuf.toString() - .trim()); - break; - case znear: - znear = Double.parseDouble(charBuf.toString() - .trim()); - break; - case zfar: - zfar = Double.parseDouble(charBuf.toString() - .trim()); - break; - case camera: - PerspectiveCamera camera = new PerspectiveCamera(true); - if (yfov != null) { - camera.setVerticalFieldOfView(true); - camera.setFieldOfView(yfov); - } else if (xfov != null) { - camera.setVerticalFieldOfView(false); - camera.setFieldOfView(xfov); - } - if (znear != null) { - camera.setNearClip(znear); - } - if (zfar != null) { - camera.setFarClip(zfar); - } - cameras.put(currentId.get("camera"), camera); - if (firstCamera == null) { - firstCamera = camera; - if (aspect_ratio != null) { - firstCameraAspectRatio = aspect_ratio; - } - } - break; - case translate: - String[] tv = charBuf.toString() - .trim() - .split("\\s+"); - currentTransforms.add(new Translate(Double.parseDouble(tv[0].trim()), - Double.parseDouble(tv[1].trim()), - Double.parseDouble(tv[2].trim()))); - break; - case rotate: - String[] rv = charBuf.toString() - .trim() - .split("\\s+"); - currentTransforms.add(new Rotate(Double.parseDouble(rv[3].trim()), - 0, 0, 0, - new Point3D(Double.parseDouble(rv[0].trim()), - Double.parseDouble(rv[1].trim()), - Double.parseDouble(rv[2].trim())))); - break; - case scale: - String[] sv = charBuf.toString() - .trim() - .split("\\s+"); - currentTransforms.add(new Scale(Double.parseDouble(sv[0].trim()), - Double.parseDouble(sv[1].trim()), - Double.parseDouble(sv[2].trim()), - 0, 0, 0)); - break; - case matrix: - String[] mv = charBuf.toString() - .trim() - .split("\\s+"); - currentTransforms.add(new Affine(Double.parseDouble(mv[0].trim()), // mxx - Double.parseDouble(mv[1].trim()), // mxy - Double.parseDouble(mv[2].trim()), // mxz - Double.parseDouble(mv[3].trim()), // tx - Double.parseDouble(mv[4].trim()), // myx - Double.parseDouble(mv[5].trim()), // myy - Double.parseDouble(mv[6].trim()), // myz - Double.parseDouble(mv[7].trim()), // ty - Double.parseDouble(mv[8].trim()), // mzx - Double.parseDouble(mv[9].trim()), // mzy - Double.parseDouble(mv[10].trim()), // mzz - Double.parseDouble(mv[11].trim()) // tz - )); - break; - case float_array: - String[] numbers = charBuf.toString() - .trim() - .split("\\s+"); - float[] array = new float[numbers.length]; - for (int i = 0; i < numbers.length; i++) { - array[i] = Float.parseFloat(numbers[i].trim()); - } - floatArrays.put(currentId.get("source"), array); - break; - case p: - numbers = charBuf.toString() - .trim() - .split("\\s+"); - int[] iArray = new int[numbers.length]; - for (int i = 0; i < numbers.length; i++) { - iArray[i] = Integer.parseInt(numbers[i].trim()); - } - pLists.add(iArray); - break; - case polygons: - // create mesh put in map - if (createPolyMesh) { - Input vertexInput = inputs.get("VERTEX"); - Input texInput = inputs.get("TEXCOORD"); - float[] points = floatArrays.get(vertexInput.source.substring(1)); - float[] texCoords = floatArrays.get(texInput.source.substring(1)); - int[][] faces = new int[pLists.size()][]; - for (int f = 0; f < faces.length; f++) { - faces[f] = pLists.get(f); - } - PolygonMesh mesh = new PolygonMesh(points, texCoords, - faces); - meshes.put(currentId.get("geometry"), mesh); - } else { - TriangleMesh mesh = new TriangleMesh(); - meshes.put(currentId.get("geometry"), mesh); - throw new UnsupportedOperationException("Need to implement TriangleMesh creation"); - } - break; - case vertices: - // put vertex float into map again with new ID - String sourceId = inputs.get("POSITION").source.substring(1); - float[] points = floatArrays.get(sourceId); - floatArrays.put(currentId.get("vertices"), points); - break; - case authoring_tool: - authoringTool = charBuf.toString() - .trim(); - break; - case vcount: - numbers = charBuf.toString() - .trim() - .split("\\s+"); - vCounts = new int[numbers.length]; - for (int i = 0; i < numbers.length; i++) { - vCounts[i] = Integer.parseInt(numbers[i].trim()); - } - break; - case polylist: - // create mesh put in map - if (createPolyMesh) { - int faceStep = 1; - Input vertexInput = inputs.get("VERTEX"); - if (vertexInput != null - && (vertexInput.offset + 1) > faceStep) { - faceStep = vertexInput.offset + 1; - } - Input texInput = inputs.get("TEXCOORD"); - if (texInput != null - && (texInput.offset + 1) > faceStep) { - faceStep = texInput.offset + 1; - } - Input normalInput = inputs.get("NORMAL"); - if (normalInput != null - && (normalInput.offset + 1) > faceStep) { - faceStep = normalInput.offset + 1; - } - points = floatArrays.get(vertexInput.source.substring(1)); - float[] texCoords; - if (texInput == null) { - texCoords = new float[] { 0, 0 }; - } else { - texCoords = floatArrays.get(texInput.source.substring(1)); - } - int[][] faces = new int[vCounts.length][]; - int[] p = pLists.get(0); - int faceIndex = 0; - for (int f = 0; f < faces.length; f++) { - final int numOfVertex = vCounts[f]; - final int[] face = new int[numOfVertex * 2]; - for (int v = 0; v < numOfVertex; v++) { - final int vertexIndex = faceIndex - + (v * faceStep); - face[v * 2] = p[vertexIndex - + vertexInput.offset]; - face[(v * 2) - + 1] = (texInput == null) ? 0 - : p[vertexIndex - + texInput.offset]; - } - faces[f] = face; - faceIndex += numOfVertex * faceStep; - } - PolygonMesh mesh = new PolygonMesh(points, texCoords, - faces); - meshes.put(currentId.get("geometry"), mesh); - } else { - TriangleMesh mesh = new TriangleMesh(); - meshes.put(currentId.get("geometry"), mesh); - throw new UnsupportedOperationException("Need to implement TriangleMesh creation"); - } - break; - default: - break; - } - } - - @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - state = state(qName); - currentId.put(qName, attributes.getValue("id")); - charBuf = new StringBuilder(); - switch (state) { - case camera: - aspect_ratio = xfov = yfov = znear = zfar = null; - break; - case visual_scene: - rootNode.setId(attributes.getValue("name")); - DaeNode rootDaeNode = new DaeNode(attributes.getValue("id"), - attributes.getValue("name")); - rootDaeNode.group = rootNode; - nodes.push(rootDaeNode); - break; - case node: - currentTransforms = new ArrayList<>(); - nodes.push(new DaeNode(attributes.getValue("id"), - attributes.getValue("name"))); - break; - case instance_camera: - nodes.peek().instance_camera = cameras.get(attributes.getValue("url") - .substring(1)); - break; - case instance_geometry: - nodes.peek().instance_geometry = meshes.get(attributes.getValue("url") - .substring(1)); - break; - case polygons: - case polylist: - inputs.clear(); - pLists.clear(); - break; - case input: - Input input = new Input(attributes.getValue("offset") != null ? Integer.parseInt(attributes.getValue("offset")) - : 0, - attributes.getValue("semantic"), - attributes.getValue("source")); - inputs.put(input.semantic, input); - break; - default: - break; - } - } - } - - private static final class Input { - public final int offset; - public final String semantic; - public final String source; - - private Input(int offset, String semantic, String source) { - this.offset = offset; - this.semantic = semantic; - this.source = source; - } - - @Override - public String toString() { - return "Input{" + "offset=" + offset + ", semantic='" + semantic - + '\'' + ", source='" + source + '\'' + '}'; - } - } - - private static enum State { - aspect_ratio, - authoring_tool, - camera, - float_array, - input, - instance_camera, - instance_geometry, - matrix, - node, - p, - polygons, - polylist, - rotate, - scale, - translate, - UNKNOWN, - vcount, - vertices, - visual_scene, - xfov, - yfov, - zfar, - znear - } - - private static State state(String name) { - try { - return State.valueOf(name); - } catch (Exception e) { - return State.UNKNOWN; - } - } - - private Map cameras = new HashMap<>(); - - private boolean createPolyMesh; - - private Camera firstCamera = null; - - private double firstCameraAspectRatio = 4 / 3; - - private Map meshes = new HashMap<>(); - - private Group rootNode = new Group(); - - { - // CHANGE FOR Y_UP - rootNode.getTransforms() - .add(new Rotate(180, 0, 0, 0, Rotate.X_AXIS)); - } - - public DaeImporter() { - } - - public DaeImporter(File file, boolean createPolyMesh) { - this.createPolyMesh = createPolyMesh; - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(file, new DaeSaxParser()); - } catch (ParserConfigurationException | SAXException | IOException e) { - e.printStackTrace(); - } - } - - public DaeImporter(InputStream in, boolean createPolyMesh) { - this.createPolyMesh = createPolyMesh; - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(in, new DaeSaxParser()); - } catch (ParserConfigurationException | SAXException | IOException e) { - e.printStackTrace(); - } - } - - public DaeImporter(String url, boolean createPolyMesh) { - load(url, createPolyMesh); - } - - public Scene createScene(int width) { - Scene scene = new Scene(rootNode, width, - (int) (width / firstCameraAspectRatio), true); - if (firstCamera != null) { - scene.setCamera(firstCamera); - } - scene.setFill(Color.BEIGE); - return scene; - } - - public Camera getFirstCamera() { - return firstCamera; - } - - @Override - public Group getRoot() { - return rootNode; - } - - @Override - public boolean isSupported(String extension) { - return extension != null && extension.equals("dae"); - } - - @Override - public void load(String url, boolean createPolygonMesh) { - this.createPolyMesh = createPolygonMesh; - long START = System.currentTimeMillis(); - try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); - saxParser.parse(url, new DaeSaxParser()); - } catch (ParserConfigurationException | SAXException | IOException e) { - e.printStackTrace(); - } - long END = System.currentTimeMillis(); - System.out.println("IMPORTED [" + url + "] in " + ((END - START)) - + "ms"); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseParser.java b/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseParser.java deleted file mode 100644 index 27efa5d..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseParser.java +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.max; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; - -import com.javafx.experiments.importers.max.MaxAseTokenizer.Callback; -import com.javafx.experiments.importers.max.MaxData.CameraNode; -import com.javafx.experiments.importers.max.MaxData.GeomNode; -import com.javafx.experiments.importers.max.MaxData.LightNode; -import com.javafx.experiments.importers.max.MaxData.MappingChannel; -import com.javafx.experiments.importers.max.MaxData.Material; -import com.javafx.experiments.importers.max.MaxData.Mesh; -import com.javafx.experiments.importers.max.MaxData.Node; -import com.javafx.experiments.importers.max.MaxData.NodeTM; - -/** Max .ase file parser */ -public class MaxAseParser { - - private class CameraNodeParser extends NodeParserBase { - CameraNode node; - - @Override - NodeTM addNodeTm() { - NodeTM ntm = new NodeTM(); - if (node.nodeTM == null) { - return node.nodeTM = ntm; - } - if (node.target == null) { - return node.target = ntm; - } - return ntm; - } - - @Override - Node createNode() { - return node = new CameraNode(); - } - - @Override - Node getNode() { - return node; - } - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*CAMERA_SETTINGS": - return this; - default: - return super.onObject(name, list); - } - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*CAMERA_NEAR": - node.near = list.nextFloat(); - break; - case "*CAMERA_FAR": - node.far = list.nextFloat(); - break; - case "*CAMERA_FOV": - node.fov = list.nextFloat(); - break; - default: - super.onValue(name, list); - } - } - } - - private class FileParserCallback extends MaxAseTokenizer.Callback { - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*SCENE": - return this; - case "*MATERIAL_LIST": - return new MaterialListParser(); - case "*LIGHTOBJECT": - return new LightNodeParser(); - case "*CAMERAOBJECT": - return new CameraNodeParser(); - case "*HELPEROBJECT": - return new NodeParser(); - case "*GEOMOBJECT": - return new GeomNodeParser(); - - } - return MaxAseTokenizer.CallbackNOP.instance; - } - - @Override - void onValue(String name, Callback.ParamList list) { - } - } - - private class GeomNodeParser extends NodeParserBase { - GeomNode n; - - @Override - Node createNode() { - return n = new GeomNode(); - } - - @Override - Node getNode() { - return n; - } - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*MESH": - return new MeshParser(n.mesh = new Mesh()); - default: - return super.onObject(name, list); - } - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*MATERIAL_REF": - n.materialRef = list.nextInt(); - break; - default: - super.onValue(name, list); - } - } - } - - private class LightNodeParser extends NodeParserBase { - LightNode n; - - @Override - Node createNode() { - return n = new LightNode(); - } - - @Override - Node getNode() { - return n; - } - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*LIGHT_SETTINGS": - return this; - default: - return super.onObject(name, list); - } - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*LIGHT_INTENS": - n.intensity = list.nextFloat(); - break; - case "*LIGHT_COLOR": - n.r = list.nextFloat(); - n.g = list.nextFloat(); - n.b = list.nextFloat(); - break; - default: - super.onValue(name, list); - } - } - - } - - private class MaterialListParser extends Callback { - Material current; - int currentMapId; - final int MAP_ID_DIFFUSE = 0; - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*MATERIAL": - current = new Material(); - data.materials[list.nextInt()] = current; - break; - - case "*MAP_DIFFUSE": - currentMapId = MAP_ID_DIFFUSE; - break; - } - return this; - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*MATERIAL_COUNT": - data.materials = new Material[list.nextInt()]; - break; - - case "*MATERIAL_NAME": - current.name = list.nextString(); - break; - case "*BITMAP": - switch (currentMapId) { - case MAP_ID_DIFFUSE: - current.diffuseMap = list.nextString(); - } - break; - case "*MATERIAL_AMBIENT": - current.ambientColor = list.nextVector(); - break; - case "*MATERIAL_DIFFUSE": - current.diffuseColor = list.nextVector(); - break; - case "*MATERIAL_SPECULAR": - current.specularColor = list.nextVector(); - break; - - } - } - } - - private static class MeshParser extends Callback { - // *MESH_FACE 3045: A: 2186 B: 2029 C: 1512 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 1,25 *MESH_MTLID 1 - private static class MeshFaceList extends Callback { - final int data[]; // a,b,c, smoothing - - MeshFaceList(int data[]) { - this.data = data; - } - - @Override - void value(byte args[][], int len[], int argc) { - int idx = parseInt(args[1], len[1]) * 4; - data[idx + 0] = parseInt(args[3], len[3]); - data[idx + 1] = parseInt(args[5], len[5]); - data[idx + 2] = parseInt(args[7], len[7]); - // String smGr = new String(args[15], 0, len[15]); - data[idx + 3] = parseSmGr(args[15], len[15]); - } - } - - private static class MeshTFaceList extends Callback { - final int data[]; - - MeshTFaceList(int data[]) { - this.data = data; - } - - @Override - void value(byte args[][], int len[], int argc) { - int idx = parseInt(args[1], len[1]) * 3; - data[idx + 0] = parseInt(args[2], len[2]); - data[idx + 1] = parseInt(args[3], len[3]); - data[idx + 2] = parseInt(args[4], len[4]); - } - } - - private static class MeshTVertexList extends Callback { - final float data[]; - - MeshTVertexList(float data[]) { - this.data = data; - } - - @Override - void value(byte args[][], int len[], int argc) { - int idx = parseInt(args[1], len[1]) * 2; - data[idx + 0] = parseFloat(args[2], len[2]); - data[idx + 1] = parseFloat(args[3], len[3]); - } - } - - private static class MeshVertexList extends Callback { - final float data[]; - - MeshVertexList(float data[]) { - this.data = data; - } - - @Override - void value(byte args[][], int len[], int argc) { - int idx = parseInt(args[1], len[1]) * 3; - data[idx + 0] = parseFloat(args[2], len[2]); - data[idx + 1] = parseFloat(args[3], len[3]); - data[idx + 2] = parseFloat(args[4], len[4]); - } - } - - static private int parseSmGr(byte data[], int l) { - int result = 0, p = 0; - while (true) { - int bit = 0; - for (; p != l && data[p] >= 0x30 && data[p] <= 0x39; ++p) { - bit = bit * 10 + data[p] - 0x30; - } - if (bit > 0) { - result |= 1 << (bit - 1); - } - if (p == l || data[p] != ',') { - break; - } else { - p++; - } - } - return result; - } - - MappingChannel mapping; - - Mesh mesh; - - private MeshParser(Mesh mesh) { - this.mesh = mesh; - } - - MappingChannel getMapping(int ch) { - if (mesh.mapping == null) { - mesh.mapping = new MappingChannel[ch + 1]; - } else if (mesh.mapping.length <= ch) { - MappingChannel m[] = new MappingChannel[ch + 1]; - System.arraycopy(mesh.mapping, 0, m, 0, mesh.mapping.length); - mesh.mapping = m; - } - - if (mesh.mapping[ch] == null) { - mesh.mapping[ch] = new MappingChannel(); - } - return mesh.mapping[ch]; - } - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*MESH_VERTEX_LIST": - return new MeshVertexList(mesh.points); - case "*MESH_FACE_LIST": - return new MeshFaceList(mesh.faces); - case "*MESH_TVERTLIST": - return new MeshTVertexList(mapping.tPoints); - case "*MESH_TFACELIST": - return new MeshTFaceList(mapping.faces); - case "*MESH_MAPPINGCHANNEL": // ignore mapping channel - default: - return MaxAseTokenizer.CallbackNOP.instance; - } - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*MESH_NUMVERTEX": - mesh.nPoints = list.nextInt(); - mesh.points = new float[mesh.nPoints * 3]; - break; - case "*MESH_NUMFACES": - mesh.nFaces = list.nextInt(); - mesh.faces = new int[mesh.nFaces * 4]; - break; - - case "*MESH_NUMTVERTEX": - if (mapping == null) { - mapping = getMapping(0); - } - mapping.ntPoints = list.nextInt(); - mapping.tPoints = new float[mapping.ntPoints * 2]; - break; - - case "*MESH_NUMTVFACES": - if (mapping == null) { - mapping = getMapping(0); - } - mapping.faces = new int[list.nextInt() * 3]; - break; - } - } - } - - private class NodeParser extends NodeParserBase { - Node n; - - @Override - Node createNode() { - return n = new Node(); - } - - @Override - Node getNode() { - return n; - } - } - - private abstract class NodeParserBase extends MaxAseTokenizer.Callback { - NodeTM addNodeTm() { - return getNode().nodeTM = new NodeTM(); - } - - abstract Node createNode(); - - abstract Node getNode(); - - @Override - Callback onObject(String name, Callback.ParamList list) { - switch (name) { - case "*NODE_TM": - return new NodeTMParser(addNodeTm()); - } - return MaxAseTokenizer.CallbackNOP.instance; - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*NODE_NAME": - addNode(createNode(), list.nextString()); - break; - case "*NODE_PARENT": - attachNode(getNode(), list.nextString()); - break; - } - } - } - - private static class NodeTMParser extends Callback { - NodeTM nodeTm; - - public NodeTMParser(NodeTM newNodeTm) { - nodeTm = newNodeTm; - } - - @Override - void onValue(String name, Callback.ParamList list) { - switch (name) { - case "*NODE_NAME": - nodeTm.name = list.nextString(); - break; - case "*TM_ROW0": - nodeTm.tm[0] = list.nextVector(); - break; - case "*TM_ROW1": - nodeTm.tm[1] = list.nextVector(); - break; - case "*TM_ROW2": - nodeTm.tm[2] = list.nextVector(); - break; - case "*TM_ROW3": - nodeTm.pos = list.nextVector(); - break; - } - } - } - - private static void attachChild(Node parent, Node n) { - if (parent.children == null) { - parent.children = new ArrayList<>(); - } - n.parent = parent; - parent.children.add(n); - } - - public MaxData data = new MaxData(); - - public MaxAseParser(InputStream stream) throws IOException { - process(stream); - } - - public MaxAseParser(String file) throws IOException { - try (FileInputStream fileInputStream = new FileInputStream(file)) { - process(fileInputStream); - } - } - - private Node addNode(Node n, String name) { - n.name = name; - data.roots.put(name, n); - data.nodes.put(name, n); - return n; - } - - private void attachNode(Node n, String parentName) { - Node parent = data.nodes.get(parentName); - if (parent != null) { - attachChild(parent, n); - data.roots.remove(n.name); - } - } - - private void process(InputStream stream) throws IOException { - MaxAseTokenizer.parse(stream, new FileParserCallback()); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseTokenizer.java b/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseTokenizer.java deleted file mode 100644 index 1ea4d37..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/max/MaxAseTokenizer.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.max; - -import java.io.IOException; -import java.io.InputStream; - -import javafx.geometry.Point3D; - -/** - * @author Kirill - */ -public class MaxAseTokenizer { - - static public class Callback { - - static public class ParamList { - byte[][] args; - int len[], argc, current = 1; - - public ParamList(byte[][] args, int[] len, int argc) { - this.args = args; - this.len = len; - this.argc = argc; - } - - public float nextFloat() { - if (argc == current) { - return 0; - } - current++; - return MaxAseTokenizer.parseFloat(args[current - 1], - len[current - 1]); - } - - public int nextInt() { - if (argc == current) { - return 0; - } - current++; - return MaxAseTokenizer.parseInt(args[current - 1], - len[current - 1]); - } - - public String nextString() { - if (argc == current) { - return null; - } - current++; - return MaxAseTokenizer.parseString(args[current - 1], - len[current - 1]); - } - - Point3D nextVector() { - return new Point3D(nextFloat(), nextFloat(), nextFloat()); - } - } - - public static float parseFloat(byte data[], int l) { - return MaxAseTokenizer.parseFloat(data, l); - } - - public static int parseInt(byte data[], int l) { - return MaxAseTokenizer.parseInt(data, l); - } - - public static String parseString(byte data[], int l) { - return MaxAseTokenizer.parseString(data, l); - } - - static boolean equals(byte data[], int len, byte cData[]) { - if (len != cData.length) { - return false; - } - for (int i = 0; i != len; ++i) { - if (data[i] != cData[i]) { - return false; - } - } - return true; - } - - Callback object(byte args[][], int len[], int argc) { - return onObject(parseString(args[0], len[0]), - new ParamList(args, len, argc)); - } - - Callback onObject(String name, ParamList list) { - return this; - } - - void onValue(String name, ParamList list) { - } - - void value(byte args[][], int len[], int argc) { - onValue(parseString(args[0], len[0]), - new ParamList(args, len, argc)); - } - } - - static public class CallbackNOP extends Callback { - static public final CallbackNOP instance = new CallbackNOP(); - - @Override - Callback object(byte args[][], int len[], int argc) { - return this; - } - - @Override - void value(byte args[][], int len[], int argc) { - } - } - - static private class ParserImpl { - final byte buffer1K[] = new byte[1024]; - final byte CLOSE = 0x7D; - final byte OPEN = 0x7B; - final InputStream stream; - private int bufferBytes = 0, bufferPos = 0; - private boolean hasData = true; - - private byte line[][] = new byte[32][]; - - private int lineLen[] = new int[32]; - - ParserImpl(InputStream inStream) { - stream = inStream; - for (int i = 0; i != line.length; ++i) { - line[i] = new byte[64]; - } - } - - private byte[] growToken(int i) { - byte line2[] = new byte[line[i].length * 2]; - System.arraycopy(line[i], 0, line2, 0, line[i].length); - return line[i] = line2; - } - - private byte[][] growTokens() { - int lineLen2[] = new int[line.length * 2]; - System.arraycopy(lineLen, 0, lineLen2, 0, line.length); - lineLen = lineLen2; - - byte line2[][] = new byte[line.length * 2][]; - System.arraycopy(line, 0, line2, 0, line.length); - return line = line2; - } - - private void parse(Callback callback) throws IOException { - while (hasData) { - int argc = parseLine(); - if (argc < 0) { - return; - } - - if (lineLen[0] == 1 && line[0][0] == CLOSE) { - return; - } - - if (lineLen[argc - 1] == 1 && line[argc - 1][0] == OPEN) { - parse(callback.object(line, lineLen, argc)); - } else { - callback.value(line, lineLen, argc); - } - } - } - - private int parseLine() throws IOException { - byte lLine[][] = line; - byte cLine[] = lLine[0]; - boolean inString = false; - for (int args = 0, len = 0;;) { - if (bufferPos == bufferBytes) { - bufferBytes = stream.read(buffer1K); - if (bufferBytes < 0) { - hasData = false; - return 0; - } - bufferPos = 0; - } - for (int i = bufferPos; i != bufferBytes; ++i) { - byte b = buffer1K[i]; - switch (b) { - case 0x0D: - break; - - case 0x0A: - bufferPos = i + 1; - lineLen[args] = len; - return len > 0 ? args + 1 : args; - - case 0x22: - inString = !inString; - break; - - case 0x20: - case 0x9: - if (!inString) { - if (len != 0) { - if (++args >= lLine.length) { - lLine = growTokens(); - } - lineLen[args - 1] = len; - cLine = lLine[args]; - len = 0; - } - break; - } - default: - if (cLine.length == len) { - cLine = growToken(args); - } - cLine[len++] = b; - } - } - bufferPos = bufferBytes; - } - } - } - - public static void parse(InputStream stream, - Callback callback) throws IOException { - new ParserImpl(stream).parse(callback); - } - - public static float parseFloat(byte data[], int l) { - float result = 0, sign = 1; - int i = 0; - byte ch = 0; - if (l > 0 && data[0] == '-') { - sign = -1; - i = 1; - } - for (; i != l; ++i) { - ch = data[i]; - if (ch >= 0x30 && ch <= 0x39) { - result = result * 10 + ch - 0x30; - } else { - break; - } - } - if (i != l && ch == '.') { - float m = 1.f; - for (++i; i != l; ++i) { - ch = data[i]; - if (ch >= 0x30 && ch <= 0x39) { - m *= 1.f / 10; - result += m * (ch - 0x30); - } else { - break; - } - } - } - - return result * sign; - } - - public static int parseInt(byte data[], int l) { - int result = 0, sign = 1, i = 0; - if (l > 0 && data[0] == '-') { - sign = -1; - i = 1; - } - for (; i != l; ++i) { - byte ch = data[i]; - if (ch >= 0x30 && ch <= 0x39) { - result = result * 10 + ch - 0x30; - } else { - break; - } - } - return result * sign; - } - - public static String parseString(byte data[], int l) { - return new String(data, 0, l); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/max/MaxData.java b/gui/src/main/java/com/javafx/experiments/importers/max/MaxData.java deleted file mode 100644 index 4480e27..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/max/MaxData.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.max; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javafx.geometry.Point3D; - -/** Max file format data objects */ -public class MaxData { - public static class CameraNode extends Node { - public float near, far, fov; - public NodeTM target; - } - - public static class GeomNode extends Node { - public int materialRef; - public Mesh mesh; - } - - public static class LightNode extends Node { - public float intensity; - public float r, g, b; - } - - public static class MappingChannel { - public int faces[]; // t0 t1 t2 - public int ntPoints; - public float tPoints[]; - } - - public static class Material { - public Point3D ambientColor; - public Point3D diffuseColor; - public String diffuseMap; - public String name; - public Point3D specularColor; - } - - public static class Mesh { - public int faces[]; // [[p0,p1,p2, smoothing]...] - public MappingChannel mapping[]; - public String name; - public int nFaces; - public int nPoints; - public float points[]; // x,y,z, x,y,z, .... - } - - public static class Node { - public List children; - public String name; - public NodeTM nodeTM; - public Node parent; - } - - public static class NodeTM { - public String name; - public Point3D pos; - public Point3D tm[] = new Point3D[3]; - } - - public Material materials[]; - public Map nodes = new HashMap<>(); - public Map roots = new HashMap<>(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/max/MaxLoader.java b/gui/src/main/java/com/javafx/experiments/importers/max/MaxLoader.java deleted file mode 100644 index b2eef57..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/max/MaxLoader.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.max; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URL; -import java.util.Map; - -import com.javafx.experiments.importers.Importer; - -import javafx.geometry.Point3D; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.PointLight; -import javafx.scene.image.Image; -import javafx.scene.paint.Color; -import javafx.scene.paint.Material; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.Mesh; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Affine; -import javafx.scene.transform.NonInvertibleTransformException; -import javafx.scene.transform.Transform; - -/** Max ASCII file loader */ -public class MaxLoader extends Importer { - public static class MaxScene extends Group { - public final Group geometry; - public final Group lights; - - public MaxScene(Group geometry, Group lights) { - this.geometry = geometry; - this.lights = lights; - getChildren().addAll(geometry, lights); - } - } - - public static String appendSuffix(String fileName, String suffix) { - int dot = fileName.lastIndexOf('.'); - String ext = fileName.substring(dot, fileName.length()); - String name = fileName.substring(0, dot); - String res = name + suffix + ext; - return res; - } - - public static String getBumpTextureName(String diffName) { - return appendSuffix(diffName, "_bp"); - } - - public static String getSpecularTextureName(String diffName) { - return appendSuffix(diffName, "_sp"); - } - - @SuppressWarnings("deprecation") - static Image loadImage(String fullName) { - Image img = null; - try { - File f = new File(fullName); - if (f.exists()) { - String url = f.toURL() - .toString(); - img = new Image(url); - } else { - System.out.println("Texture file does not exist: " + fullName); - } - } catch (Exception ex) { - System.out.println("Failed to load:" + fullName); - ex.printStackTrace(System.out); - } - return img; - } - - private static Mesh createMaxMesh(MaxData.GeomNode maxNode, Transform tm) { - Transform tmr = null; - try { - tmr = tm != null ? tm.createInverse() : null; - } catch (NonInvertibleTransformException ex) { - throw new RuntimeException(ex); - } - float vts[] = new float[maxNode.mesh.nPoints * 3]; - if (tmr != null) { - for (int i = 0; i < maxNode.mesh.nPoints; i++) { - Point3D pt = tmr.transform(maxNode.mesh.points[i * 3], - maxNode.mesh.points[i * 3 + 1], - maxNode.mesh.points[i * 3 + 2]); - vts[i * 3] = (float) pt.getX(); - vts[i * 3 + 1] = (float) pt.getY(); - vts[i * 3 + 2] = (float) pt.getZ(); - } - } else { - for (int i = 0; i < maxNode.mesh.nPoints; i++) { - vts[i * 3] = maxNode.mesh.points[i * 3]; - vts[i * 3 + 1] = maxNode.mesh.points[i * 3 + 1]; - vts[i * 3 + 2] = maxNode.mesh.points[i * 3 + 2]; - } - } - - if ((maxNode.mesh.mapping != null) - && (maxNode.mesh.mapping[0].faces.length != maxNode.mesh.nFaces)) { - //throw RuntimeException; - } - - MaxData.MappingChannel mapping = maxNode.mesh.mapping[0]; - - float uvs[] = new float[mapping.ntPoints * 2]; - for (int i = 0; i < mapping.ntPoints; i++) { - uvs[i * 2] = mapping.tPoints[i * 2]; - uvs[i * 2 + 1] = 1.0f - mapping.tPoints[i * 2 + 1]; - } - - int faces[] = new int[maxNode.mesh.nFaces * 6]; - int sg[] = new int[maxNode.mesh.nFaces]; - for (int i = 0; i < maxNode.mesh.nFaces; i++) { - int[] f = maxNode.mesh.faces; - int[] mf = mapping.faces; - faces[i * 6] = f[i * 4]; - faces[i * 6 + 1] = mf[i * 3]; - faces[i * 6 + 2] = f[i * 4 + 1]; - faces[i * 6 + 3] = mf[i * 3 + 1]; - faces[i * 6 + 4] = f[i * 4 + 2]; - faces[i * 6 + 5] = mf[i * 3 + 2]; - sg[i] = f[i * 4 + 3]; - } - - TriangleMesh mesh = new TriangleMesh(); - mesh.getPoints() - .setAll(vts); - mesh.getTexCoords() - .setAll(uvs); - mesh.getFaces() - .setAll(faces); - mesh.getFaceSmoothingGroups() - .setAll(sg); - return mesh; - } - - private static Transform loadNodeTM(MaxData.NodeTM tm) { - return new Affine(tm.tm[0].getX(), tm.tm[1].getX(), tm.tm[2].getX(), - tm.pos.getX(), tm.tm[0].getY(), tm.tm[1].getY(), - tm.tm[2].getY(), tm.pos.getY(), tm.tm[0].getZ(), - tm.tm[1].getZ(), tm.tm[2].getZ(), tm.pos.getZ()); - - } - - private Material[] materials; - - private MaxScene root; - - @Override - public Group getRoot() { - return root; - } - - @Override - public boolean isSupported(String extension) { - return extension != null && extension.equals("ase"); - } - - @Override - public void load(String fileUrl, boolean asPolygonMesh) throws IOException { - loadMaxUrl(fileUrl); - if (asPolygonMesh) { - throw new RuntimeException("Polygon Mesh is not supported"); - } else { - root = loadMaxUrl(fileUrl); - } - } - - public MaxScene loadMaxFile(File file) { - MaxData maxData = null; - try { - maxData = new MaxAseParser(file.getPath()).data; - } catch (FileNotFoundException ex) { - } catch (IOException ex) { - } - - String dir = file.getParent(); - System.out.println(dir); - - loadMaxMaterials(maxData.materials, dir); - - Group root = new Group(); - Group lroot = new Group(); - for (Map.Entry n : maxData.roots.entrySet()) { - Node node = loadMaxNode(n.getValue(), maxData); - - if (node instanceof PointLight) { // or LightBase ? - lroot.getChildren() - .add(node); - } else if (node != null) { - root.getChildren() - .add(node); - } - } - - return new MaxScene(root, lroot); - } - - public MaxScene loadMaxUrl(String fileUrl) throws IOException { - MaxData maxData = new MaxAseParser(new URL(fileUrl).openStream()).data; - - String baseUrl = fileUrl.substring(0, fileUrl.lastIndexOf('/') + 1); - - loadMaxMaterialsUrl(maxData.materials, baseUrl); - - Group root = new Group(); - Group lroot = new Group(); - for (Map.Entry n : maxData.roots.entrySet()) { - Node node = loadMaxNode(n.getValue(), maxData); - - if (node instanceof PointLight) { // or LightBase ? - lroot.getChildren() - .add(node); - } else if (node != null) { - root.getChildren() - .add(node); - } - } - - return new MaxScene(root, lroot); - } - - PointLight loadLight(MaxData.LightNode ln, Transform ntm) { - PointLight l = new PointLight(); - if (ntm != null) { - l.setTranslateX(ntm.getTx()); - l.setTranslateY(ntm.getTy()); - l.setTranslateZ(ntm.getTz()); - } - l.setColor(Color.color(ln.r, ln.g, ln.b)); - // l.setStrength(ln.intensity); // TODO - return l; - } - - private void loadMaxMaterials(MaxData.Material mtls[], String dir) { - materials = new Material[mtls.length]; - for (int i = 0; i < mtls.length; i++) { - MaxData.Material m = mtls[i]; - PhongMaterial mtl = new PhongMaterial(Color.color(m.diffuseColor.getX(), - m.diffuseColor.getY(), - m.diffuseColor.getZ())); - - String fullName = dir + File.separatorChar + m.diffuseMap; - Image diffuseMap = loadImage(fullName); - Image specularMap = loadImage(getSpecularTextureName(fullName)); - Image bumpMap = loadImage(getBumpTextureName(fullName)); - ; - - mtl.setDiffuseMap(diffuseMap); - mtl.setSpecularMap(specularMap); - mtl.setBumpMap(bumpMap); - mtl.setDiffuseColor(Color.WHITE); - materials[i] = mtl; - } - } - - private void loadMaxMaterialsUrl(MaxData.Material mtls[], String baseURl) { - materials = new Material[mtls.length]; - for (int i = 0; i < mtls.length; i++) { - MaxData.Material m = mtls[i]; - PhongMaterial mtl = new PhongMaterial(Color.color(m.diffuseColor.getX(), - m.diffuseColor.getY(), - m.diffuseColor.getZ())); - - String fullName = baseURl + m.diffuseMap; - Image diffuseMap = new Image(fullName); - Image specularMap = new Image(getSpecularTextureName(fullName)); - Image bumpMap = new Image(getBumpTextureName(fullName)); - ; - - mtl.setDiffuseMap(diffuseMap); - mtl.setSpecularMap(specularMap); - mtl.setBumpMap(bumpMap); - mtl.setDiffuseColor(Color.WHITE); - materials[i] = mtl; - } - } - - private MeshView loadMaxMeshView(MaxData.GeomNode maxNode, MaxData maxData, - Transform tm) { - Mesh mesh = createMaxMesh(maxNode, tm); - MeshView meshView = new MeshView(); - meshView.setMesh(mesh); - meshView.setMaterial(materials[maxNode.materialRef]); - // Color amb = color(maxData.materials[maxNode.materialRef].ambientColor); - //meshView.setAmbient(amb); - - meshView.setUserData(maxNode.name); - // meshView.setWireframe(true); - return meshView; - } - - private Node loadMaxNode(MaxData.Node maxNode, MaxData maxData) { - Transform ntm = loadNodeTM(maxNode.nodeTM); - - // Translate tm = new Translate(ntm.getTx(), ntm.getTy(), ntm.getTz()); - Group group = null; - if (maxNode.children != null) { - group = new Group(); - - // group.getTransforms().add(tm); - for (MaxData.Node maxChild : maxNode.children) { - Node child = loadMaxNode(maxChild, maxData); - if (child != null) { - group.getChildren() - .add(child); - } - } - } - - Node node = null; - - if (maxNode instanceof MaxData.GeomNode) { - MaxData.GeomNode geomNode = (MaxData.GeomNode) maxNode; - node = loadMaxMeshView(geomNode, maxData, null /* tm */); - } - - if ((maxNode instanceof MaxData.LightNode)) { - node = loadLight((MaxData.LightNode) maxNode, ntm); - } - - if (group != null && node != null) { - // meshView.getTransforms().add(tm); - group.getChildren() - .add(node); - } - - return group != null ? group : node; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/Frame.java b/gui/src/main/java/com/javafx/experiments/importers/maya/Frame.java deleted file mode 100644 index 37f7a56..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/Frame.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import javafx.util.Duration; - -public class Frame extends Duration { - - static final double FPS = 24.0; - private static final long serialVersionUID = 1L; - - public static Duration valueOf(double frames) { - return Duration.seconds(frames / FPS * 1000.0); - } - - Frame(double frames) { - super(frames / FPS * 1000.0); - } - - Frame(int frames) { - super(frames / FPS * 1000.0); - } - - Frame(int frames, int fps) { - super(((double) frames) / ((double) fps) * 1000.0); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/Joint.java b/gui/src/main/java/com/javafx/experiments/importers/maya/Joint.java deleted file mode 100644 index 3b86fca..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/Joint.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import javafx.scene.Group; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Translate; - -/** - * Joint - A Joint is equivalent to a Maya Joint Node - *

- * If you are post-multiplying matrices, To transform a point p from - * object-space to world-space you would need to post-multiply by the - * worldMatrix. (p' = p * wm) matrix = [S][SO][R][JO][IS][T] where R = - * [RX][RY][RZ] (Note: order is determined by rotateOrder) - *

- * If you are pre-multiplying matrices, to transform a point p from object-space - * to world-space you would need to pre-multiply by the worldMatrix. (p' = wm * - * p) matrix = [T][IS][JO][R][SO][S] where R = [RZ][RY][RX] (Note: order is - * determined by rotateOrder) Of these sub-matrices we can set [SO] to identity, - * so matrix = [T][IS][JO][R][S] - */ -public class Joint extends Group { - public final Scale is = new Scale(); - // should bind "is" to be in the inverse of the parent's "s" - - public final Rotate jox = new Rotate(); - - public final Rotate joy = new Rotate(); - - public final Rotate joz = new Rotate(); - - public final Rotate rx = new Rotate(); - - public final Rotate ry = new Rotate(); - - public final Rotate rz = new Rotate(); - - public final Scale s = new Scale(); - - public final Translate t = new Translate(); - - { - jox.setAxis(Rotate.X_AXIS); - } - - { - joy.setAxis(Rotate.Y_AXIS); - } - - { - joz.setAxis(Rotate.Z_AXIS); - } - - { - rx.setAxis(Rotate.X_AXIS); - } - - { - ry.setAxis(Rotate.Y_AXIS); - } - { - rz.setAxis(Rotate.Z_AXIS); - } - - public Joint() { - super(); - getTransforms().addAll(t, is, joz, joy, jox, rz, ry, rx, s); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/Loader.java b/gui/src/main/java/com/javafx/experiments/importers/maya/Loader.java deleted file mode 100644 index 531fe07..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/Loader.java +++ /dev/null @@ -1,1889 +0,0 @@ -/* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.javafx.experiments.importers.SmoothingGroups; -import com.javafx.experiments.importers.maya.parser.MParser; -import com.javafx.experiments.importers.maya.values.MArray; -import com.javafx.experiments.importers.maya.values.MBool; -import com.javafx.experiments.importers.maya.values.MCompound; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat; -import com.javafx.experiments.importers.maya.values.MFloat2Array; -import com.javafx.experiments.importers.maya.values.MFloat3; -import com.javafx.experiments.importers.maya.values.MFloat3Array; -import com.javafx.experiments.importers.maya.values.MFloatArray; -import com.javafx.experiments.importers.maya.values.MInt; -import com.javafx.experiments.importers.maya.values.MInt3Array; -import com.javafx.experiments.importers.maya.values.MIntArray; -import com.javafx.experiments.importers.maya.values.MPolyFace; -import com.javafx.experiments.importers.maya.values.MString; -import com.javafx.experiments.shape3d.PolygonMesh; -import com.javafx.experiments.shape3d.PolygonMeshView; -import com.javafx.experiments.shape3d.SkinningMesh; -import com.javafx.experiments.utils3d.geom.Vec3f; - -import javafx.animation.AnimationTimer; -import javafx.animation.Interpolator; -import javafx.animation.KeyValue; -import javafx.beans.property.DoubleProperty; -import javafx.scene.DepthTest; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.image.Image; -import javafx.scene.paint.Color; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.scene.transform.Affine; -import javafx.util.Duration; - -/** Loader */ -class Loader { - static class VertexHash { - private int normalIndex; - private int[] uvIndices; - private int vertexIndex; - - VertexHash(int vertexIndex, int normalIndex, int[] uvIndices) { - this.vertexIndex = vertexIndex; - this.normalIndex = normalIndex; - if (uvIndices != null) { - this.uvIndices = uvIndices.clone(); - } - } - - @Override - public boolean equals(Object arg) { - if (arg == null || !(arg instanceof VertexHash)) { - return false; - } - - VertexHash other = (VertexHash) arg; - if (vertexIndex != other.vertexIndex) { - return false; - } - if (normalIndex != other.normalIndex) { - return false; - } - if ((uvIndices != null) != (other.uvIndices != null)) { - return false; - } - if (uvIndices != null) { - if (uvIndices.length != other.uvIndices.length) { - return false; - } - for (int i = 0; i < uvIndices.length; i++) { - if (uvIndices[i] != other.uvIndices[i]) { - return false; - } - } - } - return true; - } - - @Override - public int hashCode() { - int code = vertexIndex; - code *= 17; - code += normalIndex; - if (uvIndices != null) { - for (int uvIndice : uvIndices) { - code *= 17; - code += uvIndice; - } - } - return code; - } - } - - private class SkinningMeshTimer extends AnimationTimer { - private SkinningMesh mesh; - - SkinningMeshTimer(SkinningMesh mesh) { - this.mesh = mesh; - } - - @Override - public void handle(long l) { - mesh.update(); - } - } - - public static final boolean DEBUG = false; - - public static final boolean WARN = false; - // Experimentally trying to land the frames on whole frame values - // Duration is still double, but internally, in Animation/Timeline, - // the time is discrete. 6000 units per second. - // Without this EPSILON, the frames might not land on whole frame values. - // 0.000001f seems to work for now - // 0.0000001f was too small on a trial run - static final float EPSILON = 0.000001f; - - static final float MAXIMUM = 10000000.0f; - MNodeType animCurve; - MNodeType animCurveTA; - MNodeType animCurveUA; - MNodeType animCurveUL; - MNodeType animCurveUT; - MNodeType animCurveUU; - MNodeType blendShapeType; - MNodeType blinnType; - MNodeType cameraType; - - int endFrame; - MEnv env; - MNodeType fileType; - float FPS = 24.0f; - MNodeType groupPartsType; - MNodeType jointType; - Map> keyFrameMap = new TreeMap<>(); - MNodeType lambertType; - // [Note to Alex]: I've re-enabled joints, but lets not use rootJoint [John] - // Joint rootJoint; //NO_JOINTS - Map loaded = new HashMap(); - - Map meshParents = new HashMap(); - - MNodeType meshType; - - MNodeType phongType; - - MNodeType reflectType; - MNodeType shadingEngineType; - - MNodeType skinClusterType; - int startFrame; - float TAN_CLAMPED = 10; - // Empirically derived from playing with animation curve editor - float TAN_EPSILON = 0.05f; - float TAN_FIXED = 1; - - float TAN_FLAT = 3; - - float TAN_LINEAR = 2; - - float TAN_PLATEAU = 16; - - float TAN_SPLINE = 9; - - float TAN_STEPPED = 5; - - MNodeType transformType; - - private boolean asPolygonMesh; - - // Optionally force per-face per-vertex normal generation - private int[] edgeData; - - private MFloat3Array mPointTweaks; - - private MFloat3Array mVerts; - - private URL url; - - private int uvChannel; - - private List uvSet; - - //========================================================================= - // Loader.load - //------------------------------------------------------------------------- - // Called from MayaImporter.load - //========================================================================= - public void load(URL url, boolean asPolygonMesh) { - this.url = url; - this.asPolygonMesh = asPolygonMesh; - env = new MEnv(); - MParser parser = new MParser(env); - try { - parser.parse(url); - loadModel(); - for (MNode n : env.getNodes()) { - // System.out.println("____________________________________________________________"); - // System.out.println("==> .......Node: " + n); - resolveNode(n); - } - } catch (Exception e) { - if (WARN) { - System.err.println("Error loading url: [" + url + "]"); - } - throw new RuntimeException(e); - } - } - - protected Image loadImageFromFtnAttr(MNode fileNode, String name) { - Image image = null; - MString fileName = (MString) fileNode.getAttr("ftn"); - String imageFilename = fileName.get(); - try { - File file = new File(imageFilename); - String filePath; - if (file.exists()) { - filePath = file.toURI() - .toString(); - } else { - filePath = new URL(url, imageFilename).toString(); - } - image = new Image(filePath); - if (DEBUG) { - System.out.println(name + " = " + filePath); - System.out.println(name + " w = " + image.getWidth() + " h = " - + image.getHeight()); - } - } catch (MalformedURLException ex) { - Logger.getLogger(MayaImporter.class.getName()) - .log(Level.SEVERE, - "Failed to load " + name + " '" + imageFilename + "'!", - ex); - } - return image; - } - - protected void processAnimCurve(MNode n) { - // if (DEBUG) System.out.println("processing anim curve"); - List toPaths = n.getPathsConnectingFrom("o"); - loaded.put(n, null); - for (MPath path : toPaths) { - MNode toNode = path.getTargetNode(); - // if (DEBUG) System.out.println("toNode = "+ toNode.getNodeType()); - if (toNode.isInstanceOf(transformType)) { - Node to = resolveNode(toNode); - if (to instanceof MayaGroup) { - MayaGroup g = (MayaGroup) to; - DoubleProperty ref = null; - String s = path.getComponentSelector(); - // if (DEBUG) System.out.println("selector = " + s); - if ("t[0]".equals(s)) { - ref = g.t.xProperty(); - } else if ("t[1]".equals(s)) { - ref = g.t.yProperty(); - } else if ("t[2]".equals(s)) { - ref = g.t.zProperty(); - } else if ("s[0]".equals(s)) { - ref = g.s.xProperty(); - } else if ("s[1]".equals(s)) { - ref = g.s.yProperty(); - } else if ("s[2]".equals(s)) { - ref = g.s.zProperty(); - } else if ("r[0]".equals(s)) { - ref = g.rx.angleProperty(); - } else if ("r[1]".equals(s)) { - ref = g.ry.angleProperty(); - } else if ("r[2]".equals(s)) { - ref = g.rz.angleProperty(); - } else if ("rp[0]".equals(s)) { - ref = g.rp.xProperty(); - } else if ("rp[1]".equals(s)) { - ref = g.rp.yProperty(); - } else if ("rp[2]".equals(s)) { - ref = g.rp.zProperty(); - } else if ("sp[0]".equals(s)) { - ref = g.sp.xProperty(); - } else if ("sp[1]".equals(s)) { - ref = g.sp.yProperty(); - } else if ("sp[2]".equals(s)) { - ref = g.sp.zProperty(); - } - // Note: may also want to consider adding rpt in addition to rp and sp - if (ref != null) { - convertAnimCurveRange(n, ref, true); - } - } - // [Note to Alex]: I've re-enabled joints, but not skinning yet [John] - if (to instanceof Joint) { - Joint j = (Joint) to; - DoubleProperty ref = null; - String s = path.getComponentSelector(); - // if (DEBUG) System.out.println("selector = " + s); - if ("t[0]".equals(s)) { - ref = j.t.xProperty(); - } else if ("t[1]".equals(s)) { - ref = j.t.yProperty(); - } else if ("t[2]".equals(s)) { - ref = j.t.zProperty(); - } else if ("s[0]".equals(s)) { - ref = j.s.xProperty(); - } else if ("s[1]".equals(s)) { - ref = j.s.yProperty(); - } else if ("s[2]".equals(s)) { - ref = j.s.zProperty(); - } else if ("jo[0]".equals(s)) { - ref = j.jox.angleProperty(); - } else if ("jo[1]".equals(s)) { - ref = j.joy.angleProperty(); - } else if ("jo[2]".equals(s)) { - ref = j.joz.angleProperty(); - } else if ("r[0]".equals(s)) { - ref = j.rx.angleProperty(); - } else if ("r[1]".equals(s)) { - ref = j.ry.angleProperty(); - } else if ("r[2]".equals(s)) { - ref = j.rz.angleProperty(); - } - if (ref != null) { - convertAnimCurveRange(n, ref, true); - } - } - break; - } - } - } - - protected void processClusterType(MNode n) { - loaded.put(n, null); - MArray ma = (MArray) n.getAttr("ma"); - - List jointNodes = new ArrayList(); - Set jointForest = new HashSet(); // root's children that have joints in their trees - for (int i = 0; i < ma.getSize(); i++) { - // hack... ? - MNode c = n.getIncomingConnectionToType("ma[" + i + "]", "joint"); - Joint jn = (Joint) resolveNode(c); - jointNodes.add(jn); - - Parent rootChild = jn; // root's child, which is an ancestor of joint jn - while (rootChild.getParent() != null) { - rootChild = rootChild.getParent(); - } - jointForest.add(rootChild); - } - - MNode outputMeshMNode = resolveOutputMesh(n); - MNode inputMeshMNode = resolveInputMesh(n); - if (inputMeshMNode == null || outputMeshMNode == null) { - return; - } - // We must be able to find the original converter in the meshConverters map - MNode origOrigMesh = resolveOrigInputMesh(n); - // println("ORIG ORIG={origOrigMesh}"); - - // TODO: What is with this? origMesh - resolveNode(origOrigMesh).setVisible(false); - - MArray bindPreMatrixArray = (MArray) n.getAttr("pm"); - Affine bindGlobalMatrix = convertMatrix((MFloatArray) n.getAttr("gm")); - - Affine[] bindPreMatrix = new Affine[bindPreMatrixArray.getSize()]; - for (int i = 0; i < bindPreMatrixArray.getSize(); i++) { - bindPreMatrix[i] = convertMatrix((MFloatArray) bindPreMatrixArray.getData(i)); - } - - MArray mayaWeights = (MArray) n.getAttr("wl"); - float[][] weights = new float[jointNodes.size()][mayaWeights.getSize()]; - for (int i = 0; i < mayaWeights.getSize(); i++) { - MFloatArray curWeights = (MFloatArray) mayaWeights.getData(i) - .getData("w"); - for (int j = 0; j < jointNodes.size(); j++) { - weights[j][i] = j < curWeights.getSize() ? curWeights.get(j) - : 0; - } - } - - Node sourceMayaMeshNode = resolveNode(inputMeshMNode); - Node targetMayaMeshNode = resolveNode(outputMeshMNode); - - if (sourceMayaMeshNode.getClass() - .equals(PolygonMeshView.class)) { - PolygonMeshView sourceMayaMeshView = (PolygonMeshView) sourceMayaMeshNode; - PolygonMeshView targetMayaMeshView = (PolygonMeshView) targetMayaMeshNode; - - PolygonMesh sourceMesh = sourceMayaMeshView.getMesh(); - SkinningMesh targetMesh = new SkinningMesh(sourceMesh, weights, - bindPreMatrix, - bindGlobalMatrix, - jointNodes, - new ArrayList(jointForest)); - targetMayaMeshView.setMesh(targetMesh); - - final SkinningMeshTimer skinningMeshTimer = new SkinningMeshTimer(targetMesh); - if (targetMayaMeshNode.getScene() != null) { - skinningMeshTimer.start(); - } - targetMayaMeshView.sceneProperty() - .addListener((observable, oldValue, newValue) -> { - if (newValue == null) { - skinningMeshTimer.stop(); - } else { - skinningMeshTimer.start(); - } - }); - } else { - Logger.getLogger(MayaImporter.class.getName()) - .log(Level.INFO, - "Mesh skinning is not supported for triangle meshes. Select the 'Load as Polygons' option to load the mesh as polygon mesh."); - MeshView sourceMayaMeshView = (MeshView) sourceMayaMeshNode; - MeshView targetMayaMeshView = (MeshView) targetMayaMeshNode; - TriangleMesh sourceMesh = (TriangleMesh) sourceMayaMeshView.getMesh(); - TriangleMesh targetMesh = (TriangleMesh) targetMayaMeshView.getMesh(); - targetMesh.getPoints() - .setAll(sourceMesh.getPoints()); - targetMesh.getTexCoords() - .setAll(sourceMesh.getTexCoords()); - targetMesh.getFaces() - .setAll(sourceMesh.getFaces()); - targetMesh.getFaceSmoothingGroups() - .setAll(sourceMesh.getFaceSmoothingGroups()); - } - } - - protected void processJointType(MNode n, Group parentNode) { - MFloat3 t = (MFloat3) n.getAttr("t"); - MFloat3 jo = (MFloat3) n.getAttr("jo"); - n.getAttr("r"); - MFloat3 s = (MFloat3) n.getAttr("s"); - String id = n.getName(); - - Joint j = new Joint(); - j.setId(id); - - // There's various ways to get the same thing: - // n.getAttr("r").get()[0] - // n.getAttr("r").getX() - // n.getAttr("rx") - // Up to you which you prefer - - j.t.setX(t.get()[0]); - j.t.setY(t.get()[1]); - j.t.setZ(t.get()[2]); - - // if ssc (Segment Scale Compensate) is false, then it is = 1, 1, 1 - boolean ssc = ((MBool) n.getAttr("ssc")).get(); - if (ssc) { - List parents = n.getParentNodes(); - if (parents.size() > 0) { - MFloat3 parent_s = (MFloat3) n.getParentNodes() - .get(0) - .getAttr("s"); - j.is.setX(1f / parent_s.getX()); - j.is.setY(1f / parent_s.getY()); - j.is.setZ(1f / parent_s.getZ()); - } else { - j.is.setX(1f); - j.is.setY(1f); - j.is.setZ(1f); - } - } else { - j.is.setX(1f); - j.is.setY(1f); - j.is.setZ(1f); - } - - /* - // This code doesn't seem to work right: - MFloat jox = (MFloat) n.getAttr("jox"); - MFloat joy = (MFloat) n.getAttr("joy"); - MFloat joz = (MFloat) n.getAttr("joz"); - j.jox.setAngle(jox.get()); - j.joy.setAngle(joy.get()); - j.joz.setAngle(joz.get()); - // The following code works right: - */ - - if (jo != null) { - j.jox.setAngle(jo.getX()); - j.joy.setAngle(jo.getY()); - j.joz.setAngle(jo.getZ()); - } else { - j.jox.setAngle(0f); - j.joy.setAngle(0f); - j.joz.setAngle(0f); - } - - MFloat rx = (MFloat) n.getAttr("rx"); - MFloat ry = (MFloat) n.getAttr("ry"); - MFloat rz = (MFloat) n.getAttr("rz"); - j.rx.setAngle(rx.get()); - j.ry.setAngle(ry.get()); - j.rz.setAngle(rz.get()); - - j.s.setX(s.get()[0]); - j.s.setY(s.get()[1]); - j.s.setZ(s.get()[2]); - - // Add the Joint to the map - loaded.put(n, j); - j.setDepthTest(DepthTest.ENABLE); - // Add the Joint to its JavaFX parent - if (parentNode != null) { - parentNode.getChildren() - .add(j); - if (DEBUG) { - System.out.println("j.getDepthTest() : " + j.getDepthTest()); - } - } - if (parentNode == null || !(parentNode instanceof Joint)) { - // [Note to Alex]: I've re-enabled joints, but lets not use rootJoint [John] - // rootJoint = j; - } - } - - protected void processMeshType(MNode n, - Group parentNode) throws RuntimeException { - //============================================================= - // When JavaFX supports polygon mesh geometry, - // add the polygon mesh geometry here. - // Until then, add a unit square as a placeholder. - //============================================================= - Node node = resolveNode(n.getParentNodes() - .get(0)); - // if (node != null) { - // if (node != null && !n.getName().endsWith("Orig")) { - // Original approach to mesh placeholder: - // meshParents.put(node, n); - - // Try to find an image or color from n (MNode) - if (DEBUG) { - System.out.println("________________________________________"); - } - if (DEBUG) { - System.out.println("n.getName(): " + n.getName()); - } - if (DEBUG) { - System.out.println("n.getNodeType(): " + n.getNodeType()); - } - MNode shadingGroup = n.getOutgoingConnectionToType("iog", - "shadingEngine", - true); - MNode mat; - MNode mFile; - if (DEBUG) { - System.out.println("shadingGroup: " + shadingGroup); - } - - MFloat3 mColor; - Vec3f diffuseColor = null; - Vec3f specularColor = null; - - Image diffuseImage = null; - Image normalImage = null; - Image specularImage = null; - Float specularPower = null; - - if (shadingGroup != null) { - mat = shadingGroup.getIncomingConnectionToType("ss", "lambert"); - if (mat != null) { - // shader = shaderMap.get(mat.getName()) as FixedFunctionShader; - if (DEBUG) { - System.out.println("lambert mat: " + mat); - } - mColor = (MFloat3) mat.getAttr("c"); - float diffuseIntensity = ((MFloat) mat.getAttr("dc")).get(); - if (mColor != null) { - diffuseColor = new Vec3f(mColor.get()[0] * diffuseIntensity, - mColor.get()[1] * diffuseIntensity, - mColor.get()[2] * diffuseIntensity); - if (DEBUG) { - System.out.println("diffuseColor = " + diffuseColor); - } - } - - mFile = mat.getIncomingConnectionToType("c", "file"); - if (mFile != null) { - diffuseImage = loadImageFromFtnAttr(mFile, "diffuseImage"); - } - MNode bump2d = mat.getIncomingConnectionToType("n", "bump2d"); - if (bump2d != null) { - mFile = bump2d.getIncomingConnectionToType("bv", "file"); - if (mFile != null) { - normalImage = loadImageFromFtnAttr(mFile, - "normalImage"); - } - } - } - mat = shadingGroup.getIncomingConnectionToType("ss", "phong"); - if (mat != null) { - // shader = shaderMap.get(mat.getName()) as FixedFunctionShader; - if (DEBUG) { - System.out.println("phong mat: " + mat); - } - mColor = (MFloat3) mat.getAttr("sc"); - if (mColor != null) { - specularColor = new Vec3f(mColor.get()[0], mColor.get()[1], - mColor.get()[2]); - if (DEBUG) { - System.out.println("specularColor = " + specularColor); - } - } - mFile = mat.getIncomingConnectionToType("sc", "file"); - if (mFile != null) { - specularImage = loadImageFromFtnAttr(mFile, - "specularImage"); - } - - specularPower = ((MFloat) mat.getAttr("cp")).get(); - if (DEBUG) { - System.out.println("specularPower = " + specularPower); - } - } - } - - PhongMaterial material = new PhongMaterial(); - - if (diffuseImage != null) { - material.setDiffuseMap(diffuseImage); - material.setDiffuseColor(Color.WHITE); - } else { - if (diffuseColor != null) { - material.setDiffuseColor(new Color(diffuseColor.x, - diffuseColor.y, - diffuseColor.z, 1)); - // material.setDiffuseColor(new Color( - // 0.5, - // 0.5, - // 0.5, 0)); - } else { - material.setDiffuseColor(Color.GRAY); - } - } - - if (normalImage != null) { - material.setBumpMap(normalImage); - } - - if (specularImage != null) { - material.setSpecularMap(specularImage); - } else { - if (specularColor != null && specularPower != null) { - material.setSpecularColor(new Color(specularColor.x, - specularColor.y, - specularColor.z, 1)); - material.setSpecularPower(specularPower / 33); - // material.setSpecularColor(new Color( - // 0, - // 1, - // 0, 1)); - // material.setSpecularPower(1); - } else { - // material.setSpecularColor(new Color( - // 0.2, - // 0.2, - // 0.2, 1)); - // material.setSpecularPower(1); - material.setSpecularColor(null); - } - } - - Object mesh = convertToFXMesh(n); - - if (asPolygonMesh) { - PolygonMeshView mv = new PolygonMeshView(); - mv.setId(n.getName()); - mv.setMaterial(material); - mv.setMesh((PolygonMesh) mesh); - // mv.setCullFace(CullFace.NONE); //TODO - loaded.put(n, mv); - if (node != null) { - ((Group) node).getChildren() - .add(mv); - } - } else { - MeshView mv = new MeshView(); - mv.setId(n.getName()); - mv.setMaterial(material); - - // // TODO HACK for [JIRA] (RT-30449) FX 8 3D: Need to handle mirror transformation (flip culling); - // mv.setCullFace(CullFace.FRONT); - - mv.setMesh((TriangleMesh) mesh); - - loaded.put(n, mv); - if (node != null) { - ((Group) node).getChildren() - .add(mv); - } - } - } - - protected void processTransformType(MNode n, Group parentNode) { - MFloat3 t = (MFloat3) n.getAttr("t"); - n.getAttr("r"); - MFloat3 s = (MFloat3) n.getAttr("s"); - String id = n.getName(); - // ignore cameras - if ("persp".equals(id) || "top".equals(id) || "front".equals(id) - || "side".equals(id)) { - return; - } - - MayaGroup mGroup = new MayaGroup(); - mGroup.setId(n.getName()); - // g.setBlendMode(BlendMode.SRC_OVER); - - // if (DEBUG) System.out.println("t = " + t); - // if (DEBUG) System.out.println("r = " + r); - // if (DEBUG) System.out.println("s = " + s); - - mGroup.t.setX(t.get()[0]); - mGroup.t.setY(t.get()[1]); - mGroup.t.setZ(t.get()[2]); - - MFloat rx = (MFloat) n.getAttr("rx"); - MFloat ry = (MFloat) n.getAttr("ry"); - MFloat rz = (MFloat) n.getAttr("rz"); - mGroup.rx.setAngle(rx.get()); - mGroup.ry.setAngle(ry.get()); - mGroup.rz.setAngle(rz.get()); - - mGroup.s.setX(s.get()[0]); - mGroup.s.setY(s.get()[1]); - mGroup.s.setZ(s.get()[2]); - - MFloat rptx = (MFloat) n.getAttr("rptx"); - MFloat rpty = (MFloat) n.getAttr("rpty"); - MFloat rptz = (MFloat) n.getAttr("rptz"); - mGroup.rpt.setX(rptx.get()); - mGroup.rpt.setY(rpty.get()); - mGroup.rpt.setZ(rptz.get()); - - MFloat rpx = (MFloat) n.getAttr("rpx"); - MFloat rpy = (MFloat) n.getAttr("rpy"); - MFloat rpz = (MFloat) n.getAttr("rpz"); - mGroup.rp.setX(rpx.get()); - mGroup.rp.setY(rpy.get()); - mGroup.rp.setZ(rpz.get()); - - mGroup.rpi.setX(-rpx.get()); - mGroup.rpi.setY(-rpy.get()); - mGroup.rpi.setZ(-rpz.get()); - - MFloat sptx = (MFloat) n.getAttr("sptx"); - MFloat spty = (MFloat) n.getAttr("spty"); - MFloat sptz = (MFloat) n.getAttr("sptz"); - mGroup.spt.setX(sptx.get()); - mGroup.spt.setY(spty.get()); - mGroup.spt.setZ(sptz.get()); - - MFloat spx = (MFloat) n.getAttr("spx"); - MFloat spy = (MFloat) n.getAttr("spy"); - MFloat spz = (MFloat) n.getAttr("spz"); - mGroup.sp.setX(spx.get()); - mGroup.sp.setY(spy.get()); - mGroup.sp.setZ(spz.get()); - - mGroup.spi.setX(-spx.get()); - mGroup.spi.setY(-spy.get()); - mGroup.spi.setZ(-spz.get()); - - // Add the MayaGroup to the map - loaded.put(n, mGroup); - // Add the MayaGroup to its JavaFX parent - if (parentNode != null) { - parentNode.getChildren() - .add(mGroup); - } - } - - //========================================================================= - // Loader.addKeyframe - //========================================================================= - void addKeyframe(float t, KeyValue keyValue) { - List vals = keyFrameMap.get(t); - if (vals == null) { - vals = new LinkedList(); - keyFrameMap.put(t, vals); - } - vals.add(keyValue); - } - - //========================================================================= - // Loader.computeTangent - //========================================================================= - void computeTangent(float[] keyTimes, float[] keyValues, - boolean[] keysValid, float tangentType, - boolean inTangent, float[] computedTangent) { - float[] output = computedTangent; - if (tangentType == TAN_LINEAR) { - float x0; - float x1; - float y0; - float y1; - if (inTangent) { - if (!keysValid[0]) { - // Start of the animation curve: doesn't matter - output[0] = 1.0f; - output[1] = 0.0f; - return; - } - x0 = keyTimes[0]; - x1 = keyTimes[1]; - y0 = keyValues[0]; - y1 = keyValues[1]; - } else { - if (!keysValid[2]) { - // End of the animation curve: doesn't matter - output[0] = 1.0f; - output[1] = 0.0f; - return; - } - x0 = keyTimes[1]; - x1 = keyTimes[2]; - y0 = keyValues[1]; - y1 = keyValues[2]; - } - float dx = x1 - x0; - float dy = y1 - y0; - output[0] = dx; - output[1] = dy; - // Fall through to perform normalization - } else if (tangentType == TAN_FLAT) { - output[0] = 1.0f; - output[1] = 0.0f; - return; - } else if (tangentType == TAN_STEPPED) { - // Doesn't matter what the tangent values are -- will use discrete type interpolator - return; - } else if (tangentType == TAN_SPLINE) { - // Whether we're computing the in or out tangent, if we don't have one or the other - // keyframe, it reduces to a simpler case - if (!(keysValid[0] && keysValid[2])) { - // Reduces to the linear case - computeTangent(keyTimes, keyValues, keysValid, TAN_LINEAR, - inTangent, computedTangent); - return; - } - - // Figure out the slope between the adjacent keyframes - output[0] = keyTimes[2] - keyTimes[0]; - output[1] = keyValues[2] - keyValues[0]; - } else if (tangentType == TAN_CLAMPED) { - if (!(keysValid[0] && keysValid[2])) { - // Reduces to the linear case at the ends of the animation curve - computeTangent(keyTimes, keyValues, keysValid, TAN_LINEAR, - inTangent, computedTangent); - return; - } - - float inDiff = Math.abs(keyValues[1] - keyValues[0]); - float outDiff = Math.abs(keyValues[2] - keyValues[1]); - - if (inDiff <= TAN_EPSILON || outDiff <= TAN_EPSILON) { - // The Maya docs say that this reduces to the linear - // case. If this were true, then the apparent behavior - // would be to compute the linear tangent between the - // two keyframes which are closest together, and - // reflect that tangent about the current keyframe. - // computeTangent(keyTimes, keyValues, keysValid, TAN_LINEAR, (inDiff < outDiff), computedTangent); - - // However, experimentation in the curve editor - // clearly indicates for our test cases that flat - // rather than linear interpolation is used in this - // case. Therefore to match Maya's actual behavior - // more closely we do the following. - computeTangent(keyTimes, keyValues, keysValid, TAN_FLAT, - inTangent, computedTangent); - } else { - // Use spline tangents - computeTangent(keyTimes, keyValues, keysValid, TAN_SPLINE, - inTangent, computedTangent); - } - - return; - } else if (tangentType == TAN_PLATEAU) { - if (!(keysValid[0] && keysValid[2])) { - // Reduces to the flat case at the ends of the animation curve - computeTangent(keyTimes, keyValues, keysValid, TAN_FLAT, - inTangent, computedTangent); - return; - } - - // Otherwise, figure out whether we have any local extremum - if ((keyValues[1] > keyValues[0] && keyValues[1] > keyValues[2]) - || (keyValues[1] < keyValues[0] - && keyValues[1] < keyValues[2])) { - // Use flat tangent - computeTangent(keyTimes, keyValues, keysValid, TAN_FLAT, - inTangent, computedTangent); - } else { - // The rule is that we use spline tangents unless - // doing so would cause the curve to go outside the - // envelope of the keyvalues. To figure this out, we - // have to compute both the in and out tangents as - // though we were using splines, and see whether the - // intermediate bezier control points go outside the - // hull. - // - // Note that it doesn't matter whether we compute the - // "in" or "out" tangent at the current point -- the - // result is the same. - computeTangent(keyTimes, keyValues, keysValid, TAN_SPLINE, - inTangent, computedTangent); - - // Compute the values from the keyframe along the - // tangent 1/3 of the way to the previous and next - // keyframes - float tangent = computedTangent[1] / (computedTangent[0] * FPS); - float prev13 = keyValues[1] - - tangent * ((keyTimes[1] - keyTimes[0]) / 3.0f); - float next13 = keyValues[1] - + tangent * ((keyTimes[2] - keyTimes[1]) / 3.0f); - - if (isBetween(prev13, keyValues[0], keyValues[2]) - && isBetween(next13, keyValues[0], keyValues[2])) { - } else { - // Use flat tangent - computeTangent(keyTimes, keyValues, keysValid, TAN_FLAT, - inTangent, computedTangent); - } - } - - return; - } - - // Perform normalization - // NOTE the scaling of the X coordinate -- this is needed to match Maya's math - output[0] /= FPS; - float len = (float) Math.sqrt(output[0] * output[0] - + output[1] * output[1]); - if (len != 0.0f) { - output[0] /= len; - output[1] /= len; - } - // println("TAN LINEAR {output[0]} {output[1]}"); - } - - //========================================================================= - // Loader.convertAnimCurveRange - //------------------------------------------------------------------------- - // This method adds to keyFrameMap which is a - // TreeMap Map> - //========================================================================= - void convertAnimCurveRange(MNode n, final DoubleProperty property, - boolean convertAnglesToDegrees) { - Collection inputs = n.getConnectionsTo("i"); - inputs.size(); - boolean useTangentInterpolator = true; // use the NEW tangent interpolator - - //--------------------------------------------------------------------- - // Tangent types we need to handle: - // 2 = Linear - // - The in/out tangent points in the direction of the previous/next key - // 3 = Flat - // - The in/out tangent has no y component - // 5 = Stepped - // - If this is seen on the out tangent of the previous - // frame, immediately goes to the next value - // 9 = Spline - // - The in / out tangents around the current keyframe - // match the slope defined by the previous and next - // keyframes. - // 10 = Clamped - // - Uses spline tangents unless the keyframe is very close to the next or - // previous value, in which case it uses linear tangents. - // 16 = Plateau - // - Generally speaking, if the keyframe is a local maximum or minimum, - // uses flat tangents to prevent the curve from overshooting the keyframe. - // Seems to use spline tangents when the keyframe is not a local extremum. - // There is an epsilon factor built in when deciding whether the flattening - // behavior is to be applied. - // Tangent types we aren't handling: - // 1 = Fixed - // 17 = StepNext - //--------------------------------------------------------------------- - - MArray ktv = (MArray) n.getAttr("ktv"); - MInt tan = (MInt) n.getAttr("tan"); - int len = ktv.getSize(); - - // Note: the kix, kiy, kox, koy from Maya - // are most likely unit vectors [kix, kiy] and [kox, koy] - // in some tricky units that Ken figured out. - MFloatArray kix = (MFloatArray) n.getAttr("kix"); - MFloatArray kiy = (MFloatArray) n.getAttr("kiy"); - MFloatArray kox = (MFloatArray) n.getAttr("kox"); - MFloatArray koy = (MFloatArray) n.getAttr("koy"); - MIntArray kit = (MIntArray) n.getAttr("kit"); - MIntArray kot = (MIntArray) n.getAttr("kot"); - kix.get(); - kix.get(); - boolean isRotation = n.isInstanceOf(animCurveTA) - || n.isInstanceOf(animCurveUA); - boolean keyTimesInSeconds = (n.isInstanceOf(animCurveUA) - || n.isInstanceOf(animCurveUL) - || n.isInstanceOf(animCurveUT) - || n.isInstanceOf(animCurveUU)); - - new LinkedList(); - - // Many incoming animation curves start at keyframe 1; to - // correctly interpret these we need to subtract off one frame - // from each key time - boolean needsOneFrameAdjustment = false; - - // For computing tangents around the current point - float[] keyTimes = new float[3]; - float[] keyValues = new float[3]; - boolean[] keysValid = new boolean[3]; - float[] prevOutTan = new float[3]; // for orig interpolator - float[] curOutTan = new float[3]; // for tan interpolator - float[] curInTan = new float[3]; // for both interpolators - Collection toPaths = n.getPathsConnectingFrom("o"); - for (Object obj : toPaths) { - MPath toPath = (MPath) obj; - toPath.getComponentSelector(); - toPath.getTargetNode() - .getName(); - } - - for (int j = 0; j < len; j++) { - MCompound k1 = (MCompound) ktv.getData(j); - - float kt = ((MFloat) k1.getData("kt")).get(); - float kv = ((MFloat) k1.getData("kv")).get(); - if (j == 0 && !keyTimesInSeconds) { - needsOneFrameAdjustment = (kt != 0.0f); - // if (DEBUG) System.out.println("needsOneFrameAdjustment = " + needsOneFrameAdjustment); - } - - //------------------------------------------------------------ - // Find out the previous times, values, and durations, - // if they exist - // (this code is both for tan interpolator and orig interpolator) - // Ken's duration is now called durationPrev - // Ken's k0 is now called kPrev - //------------------------------------------------------------ - float durationPrev = 0.0f; - float ktPrev = 0.0f; - if (j > 0) { - MCompound kPrev = (MCompound) ktv.getData(j - 1); - ktPrev = ((MFloat) kPrev.getData("kt")).get(); - ((MFloat) kPrev.getData("kv")).get(); - durationPrev = kt - ktPrev; - } - - //------------------------------------------------------------ - // Find out the next times, values, and durations, - // if they exist - // (this code is specifically for TangentInterpolator) - //------------------------------------------------------------ - float durationNext = 0.0f; - float ktNext = 0.0f; - if ((j + 1) < len) { - MCompound kNext = (MCompound) ktv.getData(j + 1); - ktNext = ((MFloat) kNext.getData("kt")).get(); - ((MFloat) kNext.getData("kv")).get(); - durationNext = ktNext - kt; - } - - if (!keyTimesInSeconds) { - // convert frames to seconds - kt /= FPS; - ktPrev /= FPS; // NEW - ktNext /= FPS; // NEW - } else { - // convert seconds to frames - durationPrev *= FPS; - durationNext *= FPS; // NEW - } - /* - var ktd = kt; - if (range != null) { - if (range.start > ktd or range.end < ktd) { - continue; - } - } - */ - - // Determine the tangent types on both sides - int prevOutTanType = tan.get(); // for orig interpolator - int curInTanType = tan.get(); // for both interpolators - int curOutTanType = tan.get(); // for tan intepolator - if (j > 0 && j < kot.getSize()) { - int tmp = kot.get(j - 1); - // Will be 0 if not actually written in the file - if (tmp != 0) { - prevOutTanType = tmp; - } - } - if (j < kot.getSize()) { // NEW - int tmp = kot.get(j); - if (tmp != 0) { - curOutTanType = tmp; - } - } - if (j < kit.getSize()) { - int tmp = kit.get(j); - if (tmp != 0) { - curInTanType = tmp; - } - } - - // Get previous out tangent - getTangent(ktv, kix, kiy, kox, koy, j - 1, prevOutTanType, false, - isRotation, keyTimesInSeconds, prevOutTan, - // Temporaries - keyTimes, keyValues, keysValid); - - // NEW - // for tangentInterpolator, we also need curOutTangent - // Get current out tangent - getTangent(ktv, kix, kiy, kox, koy, j, curOutTanType, false, - isRotation, keyTimesInSeconds, curOutTan, - // Temporaries - keyTimes, keyValues, keysValid); - - // Get current in tangent - getTangent(ktv, kix, kiy, kox, koy, j, curInTanType, true, - isRotation, keyTimesInSeconds, curInTan, - // Temporaries - keyTimes, keyValues, keysValid); - - // Create the appropriate interpolator type: - // [*] DISCRETE for STEPPED type for prevOutTanType - // [*] Interpolator.TANGENT - // [*] custom Maya animation curve interpolator if specified - Interpolator interp = Interpolator.DISCRETE; - if (prevOutTanType == TAN_STEPPED) { - // interp = DISCRETE; - } else { - if (useTangentInterpolator) { - //-------------------------------------------------- - // TangentIntepolator - double k_ix = curInTan[0]; - double k_iy = curInTan[1]; - // don't use prevOutTan for tangentInterpolator - // double k_ox = prevOutTan[0]; - // double k_oy = prevOutTan[1]; - double k_ox = curOutTan[0]; - double k_oy = curOutTan[1]; - - /* - if (DEBUG) System.out.println("n.getName(): " + n.getName()); - if (DEBUG) System.out.println("(k_ix = " + k_ix + ", " + - "k_iy = " + k_iy + ", " + - "k_ox = " + k_ox + ", " + - "k_oy = " + k_oy + ")" - ); - */ - - // if (DEBUG) System.out.println("FPS = " + FPS); - - double inTangent = 0.0; - double outTangent = 0.0; - - // Compute the in tangent - if (k_ix != 0) { - inTangent = k_iy / (k_ix * FPS); - } - // Compute the out tangent - if (k_ox != 0) { - outTangent = k_oy / (k_ox * FPS); - } - - // Compute 1/3 of the time interval of this keyframe - double oneThirdDeltaPrev = durationPrev / 3.0f; - double oneThirdDeltaNext = durationNext / 3.0f; - - // Note: for angular animation curves, the tangents encode - // changes in radians rather than degrees. Now that our - // animation curves also emit radians, no conversion is - // necessary here. - double inTangentValue = -1 * inTangent * oneThirdDeltaPrev - + kv; - double outTangentValue = outTangent * oneThirdDeltaNext - + kv; - // We need to add "+ kv", because the value for the tangent - // interpolator is in "world space" and not relative to the key - - if (inTangentValue > MAXIMUM) { - inTangentValue = MAXIMUM; - } - if (outTangentValue > MAXIMUM) { - outTangentValue = MAXIMUM; - } - - double timeDeltaPrev = (durationPrev / FPS) * 1000f / 3.0f; // in ms - double timeDeltaNext = (durationNext / FPS) * 1000f / 3.0f; // in ms - - if (true) { - // if (DEBUG) System.out.println("________________________________________"); - // if (DEBUG) System.out.println("n.getName() = " + n.getName()); - // if (DEBUG) System.out.println("kv = " + kv); - // if (DEBUG) System.out.println("Interpolator.TANGENT(" + - // "Duration.valueOf(" + - // timeDeltaPrev + ")" + ", " + - // inTangentValue + ", " + - // "Duration.valueOf(" + - // timeDeltaNext + ")" + ", " + - // outTangentValue + ");" - // ); - - } - - //-------------------------------------------------- - // Given the diagram below, where - // k = keyframe - // i = inTangent - // o = outTangent - // + = timeDelta - // Its extremely important to note that - // inTangent's and outTangent's values for "i" and "o" - // are NOT relative to "k". They are in "worldSpace". - // However, the timeDeltaNext and timeDeltaPrev - // are in fact relative to the keyframe "k", - // and are always an absolute value. - // So, in summary, - // the Y-axis values are not relative, but - // the X-axis values are relative, and always positive - //-------------------------------------------------- - // (Y-axis worldSpace value for i) - // inTangent i - // | - // | timeDeltaNext (relative to x) - // | |<------->| - // +---------k---------+ - // |<------->| | - // timeDeltaPrev | - // | - // o outTangent - // (Y-axis worldSpace value for o) - //-------------------------------------------------- - Duration inDuration = Duration.millis(timeDeltaPrev); - if (inDuration.toMillis() == 0) { - interp = Interpolator.TANGENT(Duration.millis(timeDeltaNext), - outTangentValue); - } else { - interp = Interpolator.TANGENT(inDuration, - inTangentValue, - Duration.millis(timeDeltaNext), - outTangentValue); - } - } else { - MayaAnimationCurveInterpolator mayaInterp = createMayaAnimationCurveInterpolator(prevOutTan[0], - prevOutTan[1], - curInTan[0], - curInTan[1], - durationPrev, - true); - // mayaInterp.isRotation = isRotation; // was commented out long ago by Ken/Chris - // mayaInterp.debug = targetName + "." + keyName + "@"+ kt; - interp = mayaInterp; - } - } - - float t = kt - EPSILON; - if (t < 0.0) { - continue; // just skipping all the negative frames - } - - /* - // This was the old way of adjusting - // for the one frame adjustment. - if (needsOneFrameAdjustment) { - t = kt - 1.0f/FPS; - } else { - t = kt; - } - // The new way is below ... - // See: (needsOneFrameAdjustment && (j == 0)) - */ - - // if (DEBUG) System.out.println("j = " + j); - // if (DEBUG) System.out.println("t = " + t); - if (isRotation) { - // Maya angular animation curves implicitly output in radians. - // In order to properly process them throughout the utility node - // network, we have to follow this convention, and implicitly - // convert the inputs of transforms' rotation angles to degrees - // at the end. - if (!convertAnglesToDegrees) { - kv = (float) Math.toRadians(kv); - } - } - // if (DEBUG) System.out.println("creating key value at: " + t + ": " + targetName + "." + keyName); - KeyValue keyValue = new KeyValue(property, kv, interp); // [!] API change - - // If the first frame is at frame 1, - // at least for now, try adding in a frame at frame 0 - // which is a duplicate of the frame at frame 1, - // to counter-act some strange behavior we are seeing - // if there is no key at frame 0. - if (needsOneFrameAdjustment && (j == 0)) { - if (DEBUG) { - System.out.println("[!] ATTEMPTING FRAME ONE ADJUSTMENT [!]"); - } - // [!] API change - // KeyValue keyValue0 = new KeyValue(property, kv, Interpolator.LINEAR); - KeyValue keyValue0 = new KeyValue(property, kv); - addKeyframe(0.0f, keyValue0); - } - - // Add keyframe - addKeyframe(t, keyValue); - - /* - // If you're at the last keyframe, - // at least for now, try adding in an extra frame - // to pad the ending - if (j == (len - 1)) { - addKeyframe((t+0.0001667f), keyValue); - } - */ - } - } - - Affine convertMatrix(MFloatArray mayaMatrix) { - if (mayaMatrix == null || mayaMatrix.getSize() < 16) { - return new Affine(); - } - - Affine result = new Affine(); - result.setMxx(mayaMatrix.get(0 * 4 + 0)); - result.setMxy(mayaMatrix.get(1 * 4 + 0)); - result.setMxz(mayaMatrix.get(2 * 4 + 0)); - result.setMyx(mayaMatrix.get(0 * 4 + 1)); - result.setMyy(mayaMatrix.get(1 * 4 + 1)); - result.setMyz(mayaMatrix.get(2 * 4 + 1)); - result.setMzx(mayaMatrix.get(0 * 4 + 2)); - result.setMzy(mayaMatrix.get(1 * 4 + 2)); - result.setMzz(mayaMatrix.get(2 * 4 + 2)); - result.setTx(mayaMatrix.get(3 * 4 + 0)); - result.setTy(mayaMatrix.get(3 * 4 + 1)); - result.setTz(mayaMatrix.get(3 * 4 + 2)); - return result; - } - - //========================================================================= - // Loader.createMayaAnimationCurveInterpolator - //========================================================================= - MayaAnimationCurveInterpolator createMayaAnimationCurveInterpolator(float kox, - float koy, - float kix, - float kiy, - float duration, - boolean hasTangent) { - if (duration == 0.0f) { - return new MayaAnimationCurveInterpolator(0, 0, true); - } else { - // Compute the out tangent - float outTangent = koy / (kox * FPS); - // Compute the in tangent - float inTangent = kiy / (kix * FPS); - // Compute 1/3 of the time interval of this keyframe - float oneThirdDelta = duration / 3.0f; - - // Note: for angular animation curves, the tangents encode - // changes in radians rather than degrees. Now that our - // animation curves also emit radians, no conversion is - // necessary here. - float p1Delta = outTangent * oneThirdDelta; - float p2Delta = -inTangent * oneThirdDelta; - return new MayaAnimationCurveInterpolator(p1Delta, p2Delta, false); - } - } - - //========================================================================= - // Loader.getTangent - //========================================================================= - void getTangent(MArray ktv, MFloatArray kix, MFloatArray kiy, - MFloatArray kox, MFloatArray koy, int index, - int tangentType, boolean inTangent, boolean isRotation, - boolean keyTimesInSeconds, float[] result, - // Temporaries - float[] tmpKeyTimes, float[] tmpKeyValues, - boolean[] tmpKeysValid) { - float[] output = result; - float[] keyTimes = tmpKeyTimes; - float[] keyValues = tmpKeyValues; - boolean[] keysValid = tmpKeysValid; - if (inTangent) { - if (index >= 0 && index < kix.getSize() && index < kiy.getSize()) { - output[0] = kix.get(index); - output[1] = kiy.get(index); - if (output[0] != 0.0f || output[1] != 0.0f) { - // A keyframe was specified in the file - return; - } - } - } else { - if (index >= 0 && index < kox.getSize() && index < koy.getSize()) { - output[0] = kox.get(index); - output[1] = koy.get(index); - if (output[0] != 0.0f || output[1] != 0.0f) { - // A keyframe was specified in the file - return; - } - } - } - - // Need to compute the tangent from the surrounding key times and values - int i = -1; - while (i < 2) { - int cur = index + i; - if (cur >= 0 && cur < ktv.getSize()) { - MCompound k1 = (MCompound) ktv.getData(cur); - float kt = ((MFloat) k1.getData("kt")).get(); - if (keyTimesInSeconds) { - // Convert seconds to frames - kt *= FPS; - } - float kv = ((MFloat) k1.getData("kv")).get(); - if (isRotation) { - // Maya angular animation curves implicitly output in radians -- see below - kv = (float) Math.toRadians(kv); - } - keyTimes[1 + i] = kt; - keyValues[1 + i] = kv; - keysValid[1 + i] = true; - } else { - keysValid[1 + i] = false; - } - ++i; - } - computeTangent(keyTimes, keyValues, keysValid, tangentType, inTangent, - result); - } - - //========================================================================= - // Loader.isBetween - //========================================================================= - boolean isBetween(float value, float v1, float v2) { - return ((v1 <= value && value <= v2) || (v1 >= value && value >= v2)); - } - - //========================================================================= - // Loader.loadModel - //========================================================================= - void loadModel() { - startFrame = Math.round(env.getPlaybackStart() - 1); - endFrame = Math.round(env.getPlaybackEnd() - 1); - transformType = env.findNodeType("transform"); - jointType = env.findNodeType("joint"); - meshType = env.findNodeType("mesh"); - cameraType = env.findNodeType("camera"); - animCurve = env.findNodeType("animCurve"); - animCurveTA = env.findNodeType("animCurveTA"); - animCurveUA = env.findNodeType("animCurveUA"); - animCurveUL = env.findNodeType("animCurveUL"); - animCurveUT = env.findNodeType("animCurveUT"); - animCurveUU = env.findNodeType("animCurveUU"); - - lambertType = env.findNodeType("lambert"); - reflectType = env.findNodeType("reflect"); - blinnType = env.findNodeType("blinn"); - phongType = env.findNodeType("phong"); - fileType = env.findNodeType("file"); - skinClusterType = env.findNodeType("skinCluster"); - groupPartsType = env.findNodeType("groupParts"); - shadingEngineType = env.findNodeType("shadingEngine"); - blendShapeType = env.findNodeType("blendShape"); - } - - //========================================================================= - // Loader.processNode - //========================================================================= - void processNode(MNode n) { - Group parentNode = null; - for (MNode p : n.getParentNodes()) { - parentNode = (Group) resolveNode(p); - } - Node result = loaded.get(n); - // if the result is null, then it hasn't been added to the map yet - // so go ahead and process it - if (result == null) { - if (n.isInstanceOf(shadingEngineType)) { - // System.out.println("==> Found a node of shadingEngineType: " + n); - } else if (n.isInstanceOf(lambertType)) { - // System.out.println("==> Found a node of lambertType: " + n); - } else if (n.isInstanceOf(reflectType)) { - // System.out.println("==> Found a node of reflectType: " + n); - } else if (n.isInstanceOf(blinnType)) { - // System.out.println("==> Found a node of blinnType: " + n); - } else if (n.isInstanceOf(phongType)) { - // System.out.println("==> Found a node of phongType: " + n); - } else if (n.isInstanceOf(fileType)) { - // System.out.println("==> Found a node of fileType: " + n); - } else if (n.isInstanceOf(skinClusterType)) { - processClusterType(n); - } else if (n.isInstanceOf(meshType)) { - processMeshType(n, parentNode); - } else if (n.isInstanceOf(jointType)) { - processJointType(n, parentNode); - } else if (n.isInstanceOf(transformType)) { - processTransformType(n, parentNode); - } else if (n.isInstanceOf(animCurve)) { - processAnimCurve(n); - } - } - } - - MNode resolveInputMesh(MNode n) { - return resolveInputMesh(n, true); - } - - MNode resolveInputMesh(MNode n, boolean followBlend) { - MNode groupParts; - if (!n.isInstanceOf(groupPartsType)) { - groupParts = n.getIncomingConnectionToType("ip[0].ig", - "groupParts"); - } else { - groupParts = n; - } - MNode origMesh = groupParts.getPathsConnectingTo("ig") - .get(0) - .getTargetNode(); - if (origMesh == null) { - MNode tweak = groupParts.getIncomingConnectionToType("ig", "tweak"); - groupParts = tweak.getIncomingConnectionToType("ip[0].ig", - "groupParts"); - origMesh = groupParts.getPathsConnectingTo("ig") - .get(0) - .getTargetNode(); - } - // println("N={n} ORIG_MESH={origMesh}"); - if (origMesh == null) { - return null; - } - if (origMesh.isInstanceOf(meshType)) { - return origMesh; - } - if (origMesh.isInstanceOf(blendShapeType)) { - // return the blend shape's output - return resolveOutputMesh(origMesh); - } - return resolveInputMesh(origMesh); - } - - //========================================================================= - // Loader.resolveNode - //------------------------------------------------------------------------- - // Loader.resolveNode looks up MNode in the HashMap Map loaded - // and returns the Node to which this map maps the MNode. - // Also, if the node that its looking up hasn't been processed yet, - // it processes the node. - //========================================================================= - Node resolveNode(MNode n) { - // System.out.println("--> resolveNode: " + n); - // if the node hasn't already been processed, then process the node - if (!loaded.containsKey(n)) { - // System.out.println("--> containsKey: " + n); - processNode(n); - // System.out.println(" loaded.get(n) " + loaded.get(n)); - } - return loaded.get(n); - } - - MNode resolveOrigInputMesh(MNode n) { - - MNode groupParts; - if (!n.isInstanceOf(groupPartsType)) { - groupParts = n.getIncomingConnectionToType("ip[0].ig", - "groupParts"); - } else { - groupParts = n; - } - MNode origMesh = groupParts.getPathsConnectingTo("ig") - .get(0) - .getTargetNode(); - if (origMesh == null) { - MNode tweak = groupParts.getIncomingConnectionToType("ig", "tweak"); - groupParts = tweak.getIncomingConnectionToType("ip[0].ig", - "groupParts"); - origMesh = groupParts.getPathsConnectingTo("ig") - .get(0) - .getTargetNode(); - } - if (origMesh == null) { - return null; - } - // println("N={n} ORIG_MESH={origMesh}"); - if (origMesh.isInstanceOf(meshType)) { - return origMesh; - } - return resolveOrigInputMesh(origMesh); - } - - MNode resolveOutputMesh(MNode n) { - MNode og; - List ogc0 = n.getPathsConnectingFrom("og[0]"); - if (ogc0.size() > 0) { - og = ogc0.get(0) - .getTargetNode(); - } else { - ogc0 = n.getPathsConnectingFrom("og"); - if (ogc0.size() > 0) { - og = ogc0.get(0) - .getTargetNode(); - } else { - return null; - } - } - if (og.isInstanceOf(meshType)) { - return og; - } - // println("r.OG={og}"); - while (og.isInstanceOf(groupPartsType)) { - og = og.getPathsConnectingFrom("og") - .get(0) - .getTargetNode(); - } - if (og.isInstanceOf(meshType)) { - return og; - } - return resolveOutputMesh(og); - } - - private Object buildMeshData(List faces, - MFloat3Array normals) { - // Setup vertexes - float[] verts = mVerts.get(); - float[] tweaks = null; - if (mPointTweaks != null) { - tweaks = mPointTweaks.get(); - } - float[] points = new float[verts.length]; - for (int index = 0; index < verts.length; index += 3) { - if (tweaks != null && tweaks.length > index + 2) { - points[index] = verts[index] + tweaks[index]; - points[index + 1] = verts[index + 1] + tweaks[index + 1]; - points[index + 2] = verts[index + 2] + tweaks[index + 2]; - } else { - points[index] = verts[index]; - points[index + 1] = verts[index + 1]; - points[index + 2] = verts[index + 2]; - } - } - - // copy UV as-is (if any) - float[] texCoords = getTexCoords(uvChannel); - - if (asPolygonMesh) { - List ff = new ArrayList(); - for (int f = 0; f < faces.size(); f++) { - MPolyFace.FaceData faceData = faces.get(f); - int[] faceEdges = faceData.getFaceEdges(); - int[][] uvData = faceData.getUVData(); - int[] uvIndices = uvData == null ? null : uvData[uvChannel]; - if (faceEdges != null && faceEdges.length > 0) { - int[] polyFace = new int[faceEdges.length * 2]; - for (int i = 0; i < faceEdges.length; i++) { - int vIndex = edgeStart(faceEdges[i]); - int uvIndex = uvIndices == null ? 0 : uvIndices[i]; - polyFace[i * 2] = vIndex; - polyFace[i * 2 + 1] = uvIndex; - } - ff.add(polyFace); - } - } - int[][] facesArray = ff.toArray(new int[ff.size()][]); - - int[][] faceNormals = new int[facesArray.length][]; - int normalInd = 0; - for (int f = 0; f < faceNormals.length; f++) { - faceNormals[f] = new int[facesArray[f].length / 2]; - for (int e = 0; e < faceNormals[f].length; e++) { - faceNormals[f][e] = normalInd++; - } - } - int[] smGroups; - // we can only figure out faces' normal indices if the faces' normal indices have a one-to-one ordered correspondence with the normals - if (normalInd == normals.getSize()) { - smGroups = SmoothingGroups.calcSmoothGroups(facesArray, - faceNormals, - normals.get()); - } else { - smGroups = new int[facesArray.length]; - Arrays.fill(smGroups, 1); - } - - PolygonMesh mesh = new PolygonMesh(); - mesh.getPoints() - .setAll(points); - mesh.getTexCoords() - .setAll(texCoords); - mesh.faces = facesArray; - mesh.getFaceSmoothingGroups() - .setAll(smGroups); - return mesh; - } else { - // Split the polygonal faces into triangle faces - List ff = new ArrayList(); - List nn = new ArrayList(); - int nIndex = 0; - - for (int f = 0; f < faces.size(); f++) { - MPolyFace.FaceData faceData = faces.get(f); - int[] faceEdges = faceData.getFaceEdges(); - int[][] uvData = faceData.getUVData(); - int[] uvIndices = uvData == null ? null : uvData[uvChannel]; - if (faceEdges != null && faceEdges.length > 0) { - - // Generate triangle fan about the first vertex - int vIndex0 = edgeStart(faceEdges[0]); - int uvIndex0 = uvIndices == null ? 0 : uvIndices[0]; - int nIndex0 = nIndex++; - - int vIndex1 = edgeStart(faceEdges[1]); - int uvIndex1 = uvIndices == null ? 0 : uvIndices[1]; - int nIndex1 = nIndex++; - - for (int i = 2; i < faceEdges.length; i++) { - int vIndex2 = edgeStart(faceEdges[i]); - int uvIndex2 = uvIndices == null ? 0 : uvIndices[i]; - int nIndex2 = nIndex++; - - ff.add(vIndex0); - ff.add(uvIndex0); - ff.add(vIndex1); - ff.add(uvIndex1); - ff.add(vIndex2); - ff.add(uvIndex2); - nn.add(nIndex0); - nn.add(nIndex1); - nn.add(nIndex2); - - vIndex1 = vIndex2; - uvIndex1 = uvIndex2; - } - } - } - int[] fff = new int[ff.size()]; - for (int i = 0; i < fff.length; i++) { - fff[i] = ff.get(i); - } - - TriangleMesh mesh = new TriangleMesh(); - int[] smGroups; - // we can only figure out faces' normal indices if the faces' normal indices have a one-to-one ordered correspondence with the normals - if (nIndex == normals.getSize()) { - int[] faceNormals = new int[nn.size()]; - for (int i = 0; i < faceNormals.length; i++) { - faceNormals[i] = nn.get(i); - } - smGroups = SmoothingGroups.calcSmoothGroups(mesh, fff, - faceNormals, - normals.get()); - } else { - smGroups = new int[fff.length / 6]; - Arrays.fill(smGroups, 1); - } - - mesh.getPoints() - .setAll(points); - mesh.getTexCoords() - .setAll(texCoords); - mesh.getFaces() - .setAll(fff); - mesh.getFaceSmoothingGroups() - .setAll(smGroups); - return mesh; - } - } - - private Object convertToFXMesh(MNode n) { - mVerts = (MFloat3Array) n.getAttr("vt"); - MPolyFace mPolys = (MPolyFace) n.getAttr("fc"); - mPointTweaks = (MFloat3Array) n.getAttr("pt"); - MInt3Array mEdges = (MInt3Array) n.getAttr("ed"); - edgeData = mEdges.get(); - uvSet = ((MArray) n.getAttr("uvst")).get(); - String currentUVSet = ((MString) n.getAttr("cuvs")).get(); - for (int i = 0; i < uvSet.size(); i++) { - if (((MString) uvSet.get(i) - .getData("uvsn")).get() - .equals(currentUVSet)) { - uvChannel = i; - } - } - - if (mPolys.getFaces() == null) { - if (asPolygonMesh) { - return new PolygonMesh(); - } else { - return new TriangleMesh(); - } - } - - MFloat3Array normals = (MFloat3Array) n.getAttr("n"); - return buildMeshData(mPolys.getFaces(), normals); - } - - private int edgeStart(int edgeNumber) { - return edgeVert(edgeNumber, true); - } - - private int edgeVert(int edgeNumber, boolean start) { - boolean reverse = (edgeNumber < 0); - if (reverse) { - edgeNumber = reverse(edgeNumber); - return edgeData[3 * edgeNumber + (start ? 1 : 0)]; - } else { - return edgeData[3 * edgeNumber + (start ? 0 : 1)]; - } - } - - private float[] getTexCoords(int uvChannel) { - if (uvSet == null || uvChannel < 0 || uvChannel >= uvSet.size()) { - return new float[] { 0, 0 }; - } - MCompound compound = (MCompound) uvSet.get(uvChannel); - MFloat2Array uvs = (MFloat2Array) compound.getFieldData("uvsp"); - if (uvs == null || uvs.get() == null) { - return new float[] { 0, 0 }; - } - - float[] texCoords = new float[uvs.getSize() * 2]; - float[] uvsData = uvs.get(); - for (int i = 0; i < uvs.getSize(); i++) { - //note the 1 - v - texCoords[i * 2] = uvsData[2 * i]; - texCoords[i * 2 + 1] = 1 - uvsData[2 * i + 1]; - } - return texCoords; - } - - private int reverse(int edge) { - if (edge < 0) { - return -edge - 1; - } - return edge; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MAttribute.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MAttribute.java deleted file mode 100644 index 3b9ca0c..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MAttribute.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya; - -import com.javafx.experiments.importers.maya.types.MDataType; - -public class MAttribute extends MObject { - - int childIndex = -1; - MDataType dataType; - MNodeType declaringNodeType; - String shortName; - - public MAttribute(MEnv env, String name, String shortName, MDataType type) { - super(env, name); - this.shortName = shortName; - this.dataType = type; - } - - @Override - public void accept(MEnv.Visitor visitor) { - visitor.visitAttribute(this); - } - - public int addChild() { - return ++childIndex; - } - - public MNodeType getContext() { - return declaringNodeType; - } - - public String getShortName() { - return shortName; - } - - public MDataType getType() { - return dataType; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MConnection.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MConnection.java deleted file mode 100644 index 9cbd8a5..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MConnection.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import java.util.Comparator; - -public class MConnection { - public static final Comparator SOURCE_PATH_COMPARATOR = (o1, - o2) -> { - MConnection c1 = (MConnection) o1; - MConnection c2 = (MConnection) o2; - return c1.getSourcePath() - .compareTo(c2.getSourcePath()); - }; - public static final Comparator TARGET_PATH_COMPARATOR = (o1, - o2) -> { - MConnection c1 = (MConnection) o1; - MConnection c2 = (MConnection) o2; - return c1.getTargetPath() - .compareTo(c2.getTargetPath()); - }; - - private MPath sourcePath; - - private MPath targetPath; - - public MConnection(MPath sourcePath, MPath targetPath) { - this.sourcePath = sourcePath; - this.targetPath = targetPath; - } - - @Override - public boolean equals(Object arg) { - if (!(arg instanceof MConnection)) { - return false; - } - MConnection other = (MConnection) arg; - return (sourcePath.equals(other.sourcePath) - && targetPath.equals(other.targetPath)); - } - - public MPath getSourcePath() { - return sourcePath; - } - - public MPath getTargetPath() { - return targetPath; - } - - @Override - public int hashCode() { - return sourcePath.hashCode() ^ targetPath.hashCode(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MEnv.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MEnv.java deleted file mode 100644 index 0a2dd16..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MEnv.java +++ /dev/null @@ -1,3108 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya; - -import java.io.PrintStream; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import com.javafx.experiments.importers.maya.types.MArrayType; -import com.javafx.experiments.importers.maya.types.MAttributeAliasType; -import com.javafx.experiments.importers.maya.types.MBoolType; -import com.javafx.experiments.importers.maya.types.MCharacterMappingType; -import com.javafx.experiments.importers.maya.types.MComponentListType; -import com.javafx.experiments.importers.maya.types.MCompoundType; -import com.javafx.experiments.importers.maya.types.MDataType; -import com.javafx.experiments.importers.maya.types.MFloat2ArrayType; -import com.javafx.experiments.importers.maya.types.MFloat2Type; -import com.javafx.experiments.importers.maya.types.MFloat3ArrayType; -import com.javafx.experiments.importers.maya.types.MFloat3Type; -import com.javafx.experiments.importers.maya.types.MFloatArrayType; -import com.javafx.experiments.importers.maya.types.MFloatType; -import com.javafx.experiments.importers.maya.types.MInt3ArrayType; -import com.javafx.experiments.importers.maya.types.MIntArrayType; -import com.javafx.experiments.importers.maya.types.MIntType; -import com.javafx.experiments.importers.maya.types.MMatrixType; -import com.javafx.experiments.importers.maya.types.MNurbsCurveType; -import com.javafx.experiments.importers.maya.types.MPointerType; -import com.javafx.experiments.importers.maya.types.MPolyFaceType; -import com.javafx.experiments.importers.maya.types.MStringType; -import com.javafx.experiments.importers.maya.values.MBool; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat; -import com.javafx.experiments.importers.maya.values.MFloat2; -import com.javafx.experiments.importers.maya.values.MFloat3; -import com.javafx.experiments.importers.maya.values.MInt; -import com.javafx.experiments.importers.maya.values.MPointer; -import com.javafx.experiments.importers.maya.values.MString; -import com.javafx.experiments.importers.maya.values.impl.MPointerImpl; - -public class MEnv { - - public static class Visitor { - public void visit(MData data) { - } - - public void visit(MObject obj) { - obj.accept(this); - } - - public void visitAttribute(MAttribute attr) { - } - - public void visitDataType(MDataType type) { - } - - public void visitEnv(MEnv env) { - } - - public void visitNode(MNode node) { - } - - public void visitNodeAttribute(MNode node, MAttribute attr, - MData value) { - } - - public void visitNodeType(MNodeType type) { - } - } - - static class AbstractBaseCreateType extends MNodeType { - AbstractBaseCreateType(MEnv env) { - super(env, "abstractBaseCreate"); - addSuperType(env.findNodeType("dependNode")); - } - } - - static class AddDoubleLinearType extends MNodeType { - AddDoubleLinearType(MEnv env) { - super(env, "addDoubleLinear"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "input1", "i1", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "input2", "i2", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class AimConstraint extends MNodeType { - AimConstraint(final MEnv env) { - super(env, "aimConstraint"); - addSuperType(env.findNodeType("constraint")); - addAttribute(new MAttribute(env, "target", "tg", - new MArrayType(env, - new MCompoundType(env, - "aimConstraint.tg") { - { - addField("tt", - env.findDataType("double3"), - null); - addField("trp", - env.findDataType("double3"), - null); - addField("trt", - env.findDataType("double3"), - null); - addField("tpm", - env.findDataType("matrix"), - null); - addField("tw", - env.findDataType("double"), - null); - } - }))); - addAttribute(new MAttribute(env, "aimVector", "a", - env.findDataType("double3"))); - addAlias("ax", "a.x"); - addAlias("ay", "a.y"); - addAlias("az", "a.z"); - addAttribute(new MAttribute(env, "upVector", "u", - env.findDataType("double3"))); - addAlias("ux", "u.x"); - addAlias("uy", "u.y"); - addAlias("uz", "u.z"); - addAttribute(new MAttribute(env, "worldUpVector", "wu", - env.findDataType("double3"))); - addAlias("wux", "wu.x"); - addAlias("wuy", "wu.y"); - addAlias("wuz", "wu.z"); - - addAttribute(new MAttribute(env, "restRotate", "rsrr", - env.findDataType("double3"))); - addAlias("rsrrx", "rsrr.x"); - addAlias("rsrry", "rsrr.y"); - addAlias("rsrrz", "rsrr.z"); - - addAttribute(new MAttribute(env, "offset", "o", - env.findDataType("double3"))); - addAlias("ox", "o.x"); - addAlias("oy", "o.y"); - addAlias("oz", "o.z"); - } - - @Override - protected void initNode(MNode result) { - MFloat3 v = (MFloat3) result.getAttr("a"); - v.set(1, 0, 0); - v = (MFloat3) result.getAttr("u"); - v.set(0, 1, 0); - v = (MFloat3) result.getAttr("wu"); - v.set(0, 1, 0); - } - } - - static class animCurve extends MNodeType { - static class ktv extends MCompoundType { - public ktv(MEnv env) { - super(env, "animCurve.ktv"); - addField("kt", env.findDataType("time"), - env.createData("time")); - addField("kv", env.findDataType("double"), - env.createData("double")); - } - } - - animCurve(MEnv env) { - super(env, "animCurve"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "tangentType", "tan", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "keyTimeValue", "ktv", - new MArrayType(env, new ktv(env)))); - addAttribute(new MAttribute(env, "keyTanInX", "kix", - env.findDataType("double[]"))); - addAttribute(new MAttribute(env, "keyTanInY", "kiy", - env.findDataType("double[]"))); - addAttribute(new MAttribute(env, "keyTanOutX", "kox", - env.findDataType("double[]"))); - addAttribute(new MAttribute(env, "keyTanOutY", "koy", - env.findDataType("double[]"))); - addAttribute(new MAttribute(env, "keyTanInType", "kit", - env.findDataType("enum[]"))); - addAttribute(new MAttribute(env, "keyTanOutType", "kot", - env.findDataType("enum[]"))); - addAttribute(new MAttribute(env, "apply", "a", - env.findDataType("function"))); - } - } - - static class animCurveTA extends MNodeType { - animCurveTA(MEnv env) { - super(env, "animCurveTA"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class animCurveTL extends MNodeType { - animCurveTL(MEnv env) { - super(env, "animCurveTL"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class animCurveTT extends MNodeType { - animCurveTT(MEnv env) { - super(env, "animCurveTT"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("time"))); - } - } - - static class animCurveTU extends MNodeType { - animCurveTU(MEnv env) { - super(env, "animCurveTU"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class animCurveUA extends MNodeType { - animCurveUA(MEnv env) { - super(env, "animCurveUA"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class animCurveUL extends MNodeType { - animCurveUL(MEnv env) { - super(env, "animCurveUL"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class animCurveUT extends MNodeType { - animCurveUT(MEnv env) { - super(env, "animCurveUT"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("time"))); - } - } - - static class animCurveUU extends MNodeType { - animCurveUU(MEnv env) { - super(env, "animCurveUU"); - addSuperType(env.findNodeType("animCurve")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - } - } - - static class BlendColorsType extends MNodeType { - BlendColorsType(MEnv env) { - super(env, "blendColors"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "blender", "b", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "color1", "c1", - env.findDataType("float3"))); - addAlias("color1R", "c1.x"); - addAlias("color1G", "c1.y"); - addAlias("color1B", "c1.z"); - addAlias("c1r", "c1.x"); - addAlias("c1g", "c1.y"); - addAlias("c1b", "c1.z"); - addAttribute(new MAttribute(env, "color2", "c2", - env.findDataType("float3"))); - addAlias("color2R", "c2.x"); - addAlias("color2G", "c2.y"); - addAlias("color2B", "c2.z"); - addAlias("c2r", "c2.x"); - addAlias("c2g", "c2.y"); - addAlias("c2b", "c2.z"); - addAttribute(new MAttribute(env, "output", "op", - env.findDataType("float3"))); - addAlias("outputR", "op.x"); - addAlias("outputG", "op.y"); - addAlias("outputB", "op.z"); - addAlias("opr", "op.x"); - addAlias("opg", "op.y"); - addAlias("opb", "op.z"); - } - - @Override - protected void initNode(MNode result) { - MFloat b = (MFloat) result.getAttr("b"); - b.set(0.5f); - MFloat3 c1 = (MFloat3) result.getAttr("c1"); - c1.set(1, 0, 0); - MFloat3 c2 = (MFloat3) result.getAttr("c2"); - c2.set(0, 0, 1); - } - } - - static class BlendShapeNodeType extends MNodeType { - BlendShapeNodeType(final MEnv env) { - super(env, "blendShape"); - addSuperType(env.findNodeType("geometryFilter")); - addAttribute(new MAttribute(env, "weight", "w", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "inputTarget", "it", - new MArrayType(env, - new MCompoundType(env, - "blendShape.it") { - { - - addField("itg", - new MArrayType(env, - new MCompoundType(env, - "blendShape.it.itg") { - { - addField("iti", - new MArrayType(env, - new MCompoundType(env, - "blendShape.it.itg.iti") { - { - addField("itg", - env.findDataType("geometry"), - null); - addField("ipt", - env.findDataType("pointArray"), - null); - addField("ict", - env.findDataType("componentList"), - null); - } - }), - null); - addField("tw", - env.findDataType("float[]"), - null); - } - }), - null); - } - }))); - - } - } - - static class BlendType extends MNodeType { - BlendType(MEnv env) { - super(env, "blend"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("double[]"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "current", "c", - env.findDataType("integer"))); - } - } - - // public abstract MData parseData(MDataType type, String text); - - static class BlendWeightedType extends MNodeType { - BlendWeightedType(MEnv env) { - super(env, "blendWeighted"); - addSuperType(env.findNodeType("blend")); - addAttribute(new MAttribute(env, "weight", "w", - env.findDataType("float[]"))); - } - } - - static class BlinnNodeType extends MNodeType { - BlinnNodeType(MEnv env) { - super(env, "blinn"); - addSuperType(env.findNodeType("reflect")); - addAttribute(new MAttribute(env, "eccentricity", "ec", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat ec = (MFloat) result.getAttr("ec"); - ec.set(.3f); - } - } - - static class Bump2dNodeType extends MNodeType { - Bump2dNodeType(MEnv env) { - super(env, "bump2d"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "bumpValue", "bv", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "outNormal", "o", - env.findDataType("float3"))); - } - } - - static class CameraType extends MNodeType { - CameraType(MEnv env) { - super(env, "camera"); - addSuperType(env.findNodeType("shape")); - addAttribute(new MAttribute(env, "renderable", "rnd", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "cameraAperture", "cap", - env.findDataType("double2"))); - addAlias("horizontalFilmAperture", "cap.x"); - addAlias("hfa", "cap.x"); - addAlias("verticalFilmAperture", "cap.y"); - addAlias("vfa", "cap.y"); - // 0 = fill, 1 = horizontal fit, 2 = vertical fit, 3 = overscan fit - addAttribute(new MAttribute(env, "filmFit", "ff", - env.findDataType("int"))); - addAttribute(new MAttribute(env, "imageName", "imn", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "depthName", "den", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "maskName", "man", - env.findDataType("string"))); - // In centimeters - addAttribute(new MAttribute(env, "centerOfInterest", "coi", - env.findDataType("double"))); - // In millimeters - addAttribute(new MAttribute(env, "focalLength", "fl", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "lensSqueezeRatio", "lsr", - env.findDataType("double"))); - // In centimeters - addAttribute(new MAttribute(env, "orthographicWidth", "ow", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "orthographic", "o", - env.findDataType("bool"))); - - // In centimeters - addAttribute(new MAttribute(env, "farClipPlane", "fcp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "nearClipPlane", "ncp", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MBool renderable = (MBool) result.getAttr("rnd"); - renderable.set(true); - MInt filmFit = (MInt) result.getAttr("ff"); - filmFit.set(1); // horizontal fit - MFloat centerOfInterest = (MFloat) result.getAttr("coi"); - centerOfInterest.set(5.0f); - MFloat focalLength = (MFloat) result.getAttr("fl"); - focalLength.set(35.0f); - MFloat orthographicWidth = (MFloat) result.getAttr("ow"); - orthographicWidth.set(10.0f); - MFloat2 cameraAperture = (MFloat2) result.getAttr("cap"); - cameraAperture.set(3.6f, 2.4f); - MFloat lensSqueezeRatio = (MFloat) result.getAttr("lsr"); - lensSqueezeRatio.set(1.0f); - MFloat f = (MFloat) result.getAttr("fcp"); - f.set(1000); - f = (MFloat) result.getAttr("ncp"); - f.set(.1f); - } - } - - static class cgfxShaderType extends MNodeType { - cgfxShaderType(MEnv env) { - super(env, "cgfxShader"); - addSuperType(env.findNodeType("hwShader")); - addAttribute(new MAttribute(env, "shader", "s", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "technique", "t", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "vas", "vas", - env.findDataType("stringArray"))); - addAttribute(new MAttribute(env, "val", "val", - env.findDataType("stringArray"))); - } - } - - static class cgfxVectorType extends MNodeType { - cgfxVectorType(MEnv env) { - super(env, "cgfxVector"); // ? - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "matrix", "m", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "worldVector", "wv", - env.findDataType("float3"))); - } - } - - static class CharacterType extends MNodeType { - CharacterType(MEnv env) { - super(env, "character"); - addSuperType(env.findNodeType("objectSet")); - addAttribute(new MAttribute(env, "unitlessValues", "uv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "linearValues", "lv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "angularValues", "av", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "timeValues", "tv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "animationMapping", "am", - new MArrayType(env, - env.findDataType("string")))); - } - } - - static class ChoiceNodeType extends MNodeType { - ChoiceNodeType(MEnv env) { - super(env, "choice"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "selector", "s", - env.findDataType("integer"))); - addAttribute(new MAttribute(env, "input", "i", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("Message"))); - } - } - - static class ClampType extends MNodeType { - ClampType(MEnv env) { - super(env, "clamp"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "min", "mn", - env.findDataType("float3"))); - addAlias("mnr", "mn.x"); - addAlias("mng", "mn.y"); - addAlias("mnb", "mn.z"); - addAttribute(new MAttribute(env, "com/javafx/importers/max", "mx", - env.findDataType("float3"))); - addAlias("mxr", "mx.x"); - addAlias("mxg", "mx.y"); - addAlias("mxb", "mx.z"); - addAttribute(new MAttribute(env, "input", "ip", - env.findDataType("float3"))); - addAlias("ipr", "ip.x"); - addAlias("ipg", "ip.y"); - addAlias("ipb", "ip.z"); - addAttribute(new MAttribute(env, "output", "op", - env.findDataType("float3"))); - addAlias("opr", "op.x"); - addAlias("opg", "op.y"); - addAlias("opb", "op.z"); - } - } - - static class ConditionType extends MNodeType { - ConditionType(MEnv env) { - super(env, "condition"); - addSuperType(env.findNodeType("dependNode")); - /* - Operation is the test that is performed between the First Term and Second Term attributes. If the test is true, Out Color is set to ColorIfTrue. If it is false, Out Color is set to ColorIfFalse. - The possible operations are: - - Equal - Not Equal - Greater Than - Greater Or Equal - Less Than - Less or Equal */ - addAttribute(new MAttribute(env, "operation", "op", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "firstTerm", "ft", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "secondTerm", "st", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "colorIfTrue", "ct", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "colorIfFalse", "cf", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAlias("ctr", "ct.x"); - addAlias("ctg", "ct.y"); - addAlias("ctb", "ct.z"); - addAlias("cfr", "cf.x"); - addAlias("cfg", "cf.y"); - addAlias("cfb", "cf.z"); - addAlias("ocr", "oc.x"); - addAlias("ocg", "oc.y"); - addAlias("ocb", "oc.z"); - } - - @Override - protected void initNode(MNode result) { - MFloat3 cf = (MFloat3) result.getAttr("cf"); - cf.set(1, 1, 1); - } - } - - static class Constraint extends MNodeType { - Constraint(MEnv env) { - super(env, "constraint"); - addSuperType(env.findNodeType("transform")); - addAttribute(new MAttribute(env, "enableRestPosition", "erp", - env.findDataType("bool"))); - } - } - - static class ControlPointType extends MNodeType { - static class UVSet extends MArrayType { - static class UVSetElement extends MCompoundType { - public UVSetElement(MEnv env) { - super(env, "controlPoint.uvSet"); - addField("uvsn", env.findDataType("string"), - env.createData("string")); - addField("uvsp", env.findDataType("float2[]"), - env.createData("float2[]")); - getFields().put("uvSetName", getField("uvsn")); - getFields().put("uvSetPoints", getField("uvsp")); - } - } - - public UVSet(MEnv env) { - super(env, new UVSetElement(env)); - } - } - - ControlPointType(MEnv env) { - super(env, "controlPoint"); - addSuperType(env.findNodeType("deformableShape")); - addAttribute(new MAttribute(env, "uvSet", "uvst", new UVSet(env))); - addAttribute(new MAttribute(env, "currentUVSet", "cuvs", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "tweakLocation", "twl", - env.findDataType("Message"))); - - } - } - - static class CurveShapeType extends MNodeType { - CurveShapeType(MEnv env) { - super(env, "curveShape"); - addSuperType(env.findNodeType("controlPoint")); - } - } - - static class DagNodeType extends MNodeType { - static class iogType extends MArrayType { - static class ogArrayType extends MArrayType { - public ogArrayType(MEnv env) { - super(env, new ogType(env)); - } - } - - static class ogsType extends MCompoundType { - public ogsType(MEnv env) { - super(env, "dagNode.iog.og[]"); - addField("og", new ogArrayType(env), null); - } - } - - static class ogType extends MCompoundType { - public ogType(MEnv env) { - super(env, "dagNode.iog.og"); - addField("gcl", env.findDataType("componentList"), - env.createData("componentList")); - addField("gid", env.findDataType("int"), - env.createData("int")); - addField("gco", env.findDataType("short"), - env.createData("short")); - } - } - - public iogType(MEnv env) { - super(env, new ogsType(env)); - } - } - - DagNodeType(MEnv env) { - super(env, "dagNode"); - addAttribute(new MAttribute(env, "instObjGroups", "iog", - new iogType(env))); - addAttribute(new MAttribute(env, "parentMatrix", "pm", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "parentInverseMatrix", "pim", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "visibility", "v", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "intermediateObject", "io", - env.findDataType("bool"))); - } - - @Override - protected void initNode(MNode result) { - MBool v = (MBool) result.getAttr("v"); - v.set(true); - } - } - - static class DagPoseType extends MNodeType { - DagPoseType(MEnv env) { - super(env, "dagPose"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "worldMatrix", "wm", - env.findDataType("matrix"))); - - } - } - - static class DeformableShapeType extends MNodeType { - DeformableShapeType(MEnv env) { - super(env, "deformableShape"); - addSuperType(env.findNodeType("geometryShape")); - } - } - - static class DependNodeType extends MNodeType { - DependNodeType(MEnv env) { - super(env, "dependNode"); - addAttribute(new MAttribute(env, "message", "msg", - env.findDataType("Message"))); - } - } - - static class DirectionalLightType extends MNodeType { - DirectionalLightType(MEnv env) { - super(env, "directionalLight"); - addSuperType(env.findNodeType("nonExtendedLightShapeNode")); - } - } - - static class DynBase extends MNodeType { - DynBase(MEnv env) { - super(env, "dynBase"); - addSuperType(env.findNodeType("transform")); - } - } - - static class EntityType extends MNodeType { - EntityType(MEnv env) { - super(env, "entity"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "dagSetMembers", "dsm", - env.findDataType("Message"))); - } - } - - static class Field extends MNodeType { - Field(final MEnv env) { - super(env, "field"); - addSuperType(env.findNodeType("dynBase")); - addAttribute(new MAttribute(env, "magnitude", "mag", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "attenuation", "att", - env.findDataType("double"))); - - addAttribute(new MAttribute(env, "maxDistance", - "com/javafx/importers/max", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "falloffCurve", "fc", - new MArrayType(env, - new MCompoundType(env, - "field.fc") { - { - addField("fcp", - env.findDataType("float"), - null); - - addField("fcfv", - env.findDataType("float"), - null); - - addField("fci", - env.findDataType("enum"), - null); - - } - }))); - addAttribute(new MAttribute(env, "inputData", "ind", - new MArrayType(env, - new MCompoundType(env, - "field.ind") { - { - addField("inp", - env.findDataType("float3[]"), - null); - - addField("inv", - env.findDataType("float3[]"), - null); - - addField("im", - env.findDataType("float[]"), - null); - - addField("dt", - env.findDataType("double"), - null); - - } - }))); - - addAttribute(new MAttribute(env, "outputForce", "of", - env.findDataType("float3[]"))); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("mag"); - f.set(1); - f = (MFloat) result.getAttr("com/javafx/importers/max"); - f.set(-1); - } - } - - static class FileType extends MNodeType { - FileType(MEnv env) { - super(env, "file"); - addSuperType(env.findNodeType("texture2d")); - addAttribute(new MAttribute(env, "fileTextureName", "ftn", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "outTransparency", "ot", - env.findDataType("float3"))); - addAlias("otr", "ot.x"); - addAlias("otg", "ot.y"); - addAlias("otb", "ot.z"); - } - } - - static class GeometryFilterNodeType extends MNodeType { - GeometryFilterNodeType(final MEnv env) { - super(env, "geometryFilter"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "outputGeometry", "og", - new MArrayType(env, - env.findDataType("Message")))); - ; - addAttribute(new MAttribute(env, "input", "ip", - new MArrayType(env, - new MCompoundType(env, - "geometryFilter.ip") { - { - addField("ig", - env.findDataType("Message"), - null); - addField("gi", - env.findDataType("int"), - null); - } - }))); - - } - } - - static class GeometryShapeType extends MNodeType { - GeometryShapeType(MEnv env) { - super(env, "geometryShape"); - addSuperType(env.findNodeType("shape")); - } - } - - static class GravityField extends MNodeType { - GravityField(final MEnv env) { - super(env, "gravityField"); - addSuperType(env.findNodeType("field")); - addAttribute(new MAttribute(env, "direction", "d", - env.findDataType("float3"))); - addAlias("dx", "d.x"); - addAlias("dy", "d.y"); - addAlias("dz", "d.z"); - } - } - - static class GroupIdType extends MNodeType { - GroupIdType(MEnv env) { - super(env, "groupId"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "groupId", "id", - env.findDataType("int"))); - } - } - - static class GroupPartsType extends MNodeType { - GroupPartsType(MEnv env) { - super(env, "groupParts"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "inputGeometry", "ig", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "inputComponents", "ic", - env.findDataType("componentList"))); - addAttribute(new MAttribute(env, "groupId", "gi", - env.findDataType("int"))); - } - } - - static class hwShaderType extends MNodeType { - hwShaderType(MEnv env) { - super(env, "hwShader"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "shader", "s", - env.findDataType("string"))); - } - } - - static class IKEffectorType extends MNodeType { - IKEffectorType(MEnv env) { - super(env, "ikEffector"); - addSuperType(env.findNodeType("transform")); - addAttribute(new MAttribute(env, "handlePath", "hp", - env.findDataType("Message"))); - } - } - - static class IKHandle extends MNodeType { - IKHandle(MEnv env) { - super(env, "ikHandle"); - addSuperType(env.findNodeType("transform")); - addAttribute(new MAttribute(env, "startJoint", "hsj", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "endEffector", "hee", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "weight", "hw", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "poleVector", "pv", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "roll", "rol", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "twist", "twi", - env.findDataType("double"))); - addAlias("pvx", "pv.x"); - addAlias("pvy", "pv.y"); - addAlias("pvz", "pv.z"); - } - - @Override - protected void initNode(MNode result) { - MFloat3 pv = (MFloat3) result.getAttr("pv"); - pv.set(0, 0, 1); - } - } - - static class JointNodeType extends MNodeType { - JointNodeType(MEnv env) { - super(env, "joint"); - addSuperType(env.findNodeType("transform")); - addAttribute(new MAttribute(env, "bindPose", "bps", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "jointOrient", "jo", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "jointOrientType", "jot", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "inverseParentScale", "is", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "preferredAngle", "pa", - env.findDataType("double3"))); - addAlias("pax", "pa.x"); - addAlias("pay", "pa.y"); - addAlias("paz", "pa.z"); - addAttribute(new MAttribute(env, "segmentScaleCompensate", "ssc", - env.findDataType("bool"))); - } - - @Override - protected void initNode(MNode result) { - MString jot = (MString) result.getAttr("jot"); - jot.set("xyz"); - MFloat3 is = (MFloat3) result.getAttr("is"); - is.set(1, 1, 1); - MBool ssc = (MBool) result.getAttr("ssc"); - ssc.set(true); - } - } - - static class LambertType extends MNodeType { - LambertType(MEnv env) { - super(env, "lambert"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "color", "c", - env.findDataType("float3"))); - addAlias("cr", "c.x"); - addAlias("cg", "c.y"); - addAlias("cb", "c.z"); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outTransparency", "ot", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outGlowColor", "ogc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outMatteOpacity", "omo", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "diffuse", "dc", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "ambientColor", "ambc", - env.findDataType("float3"))); - addAlias("acr", "ambc.x"); - addAlias("acg", "ambc.y"); - addAlias("acb", "ambc.z"); - addAttribute(new MAttribute(env, "incandescence", "ic", - env.findDataType("float3"))); - addAlias("ir", "ic.x"); - addAlias("ig", "ic.y"); - addAlias("ib", "ic.z"); - addAttribute(new MAttribute(env, "transparency", "it", - env.findDataType("float3"))); - addAlias("itr", "it.x"); - addAlias("itg", "it.y"); - addAlias("itb", "it.z"); - addAttribute(new MAttribute(env, "normalCamera", "n", - env.findDataType("float3"))); - addAlias("nx", "n.x"); - addAlias("ny", "n.y"); - addAlias("nz", "n.z"); - addAttribute(new MAttribute(env, "transparency", "it", - env.findDataType("float3"))); - addAlias("itr", "it.x"); - addAlias("itg", "it.y"); - addAlias("itb", "it.z"); - } - - @Override - protected void initNode(MNode node) { - MFloat dc = (MFloat) node.getAttr("dc"); - dc.set(.8f); - // MFloat3 ambc = (MFloat3)node.getAttr("ambc"); - // ambc.set(.2f, .2f, .2f); - MFloat3 c = (MFloat3) node.getAttr("c"); - c.set(.5f, .5f, .5f); - // MFloat3 ic = (MFloat3)node.getAttr("ic"); - - } - } - - static class LayeredTexture extends MNodeType { - LayeredTexture(final MEnv env) { - super(env, "layeredTexture"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAlias("oc.x", "ocr"); - addAlias("oc.y", "ocg"); - addAlias("oc.z", "ocb"); - addAttribute(new MAttribute(env, "outAlpha", "oa", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "outTransparency", "ot", - env.findDataType("float3"))); - addAlias("ot.x", "otr"); - addAlias("ot.y", "otg"); - addAlias("ot.z", "otb"); - addAttribute(new MAttribute(env, "inputs", "cs", - new MArrayType(env, - new MCompoundType(env, - "layeredTexture.cs") { - { - addField("c", - new MCompoundType(env, - "layeredTexture.cs.c") { - { - addField("cr", - env.findDataType("float"), - null); - addField("cg", - env.findDataType("float"), - null); - addField("cb", - env.findDataType("float"), - null); - } - }, - null); - - addField("a", - env.findDataType("float"), - null); - addField("bm", - env.findDataType("enum"), - null); - } - }))); - } - } - - static class LightLinkerNodeType extends MNodeType { - LightLinkerNodeType(MEnv env) { - super(env, "lightLinker"); - addSuperType(env.findNodeType("dependNode")); - } - } - - static class LightType extends MNodeType { - LightType(MEnv env) { - super(env, "light"); - addSuperType(env.findNodeType("shape")); - addAttribute(new MAttribute(env, "color", "cl", - env.findDataType("float3"))); - addAlias("cr", "cl.x"); - addAlias("cg", "cl.y"); - addAlias("cb", "cl.z"); - addAttribute(new MAttribute(env, "intensity", "in", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "li", "li", - env.findDataType("float3"))); // ??? - } - - @Override - protected void initNode(MNode result) { - MFloat3 cl = (MFloat3) result.getAttr("cl"); - cl.set(1, 1, 1); - MFloat in = (MFloat) result.getAttr("in"); - in.set(1f); - } - } - - static class MaterialInfoNodeType extends MNodeType { - MaterialInfoNodeType(MEnv env) { - super(env, "materialInfo"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "shadingGroup", "sg", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "material", "m", - env.findDataType("Message"))); - } - } - - static class MeshNodeType extends MNodeType { - MeshNodeType(MEnv env) { - super(env, "mesh"); - addSuperType(env.findNodeType("surfaceShape")); - addAttribute(new MAttribute(env, "vrts", "vt", - env.findDataType("float3[]"))); - addAttribute(new MAttribute(env, "pnts", "pt", - env.findDataType("float3[]"))); - addAttribute(new MAttribute(env, "face", "fc", - env.findDataType("polyFace"))); - addAttribute(new MAttribute(env, "edge", "ed", - env.findDataType("int3[]"))); - addAttribute(new MAttribute(env, "normals", "n", - env.findDataType("float3[]"))); - addAttribute(new MAttribute(env, "inMesh", "i", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "outMesh", "o", - env.findDataType("Message"))); - } - } - - static class MotionPathType extends MNodeType { - MotionPathType(final MEnv env) { - super(env, "motionPath"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "uValue", "u", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "frontTwist", "ft", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "upTwist", "ut", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "sideTwist", "st", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "allCoordinates", "ac", - env.findDataType("float3"))); - addAlias("ac.x", "xc"); - addAlias("ac.y", "yc"); - addAlias("ac.z", "zc"); - addAttribute(new MAttribute(env, "rotate", "r", - env.findDataType("float3"))); - addAlias("r.x", "rx"); - addAlias("r.y", "ry"); - addAlias("r.z", "rz"); - addAttribute(new MAttribute(env, "rotateOrder", "ro", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "geometryPath", "gp", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "follow", "f", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "inverseUp", "ip", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "inverseFront", "if", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "frontAxis", "fa", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "upAxis", "ua", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "worldUpVector", "wu", - env.findDataType("float3"))); - addAlias("wu.x", "wux"); - addAlias("wu.y", "wuy"); - addAlias("wu.z", "wuz"); - addAttribute(new MAttribute(env, "worldUpType", "wut", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "worldUpMatrix", "wum", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "orientMatrix", "om", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "bank", "b", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "bankScale", "bs", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "bankLimit", "bl", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "fractionMode", "fm", - env.findDataType("bool"))); - } - - @Override - protected void initNode(MNode result) { - MFloat w = (MFloat) result.getAttr("bl"); - w.set(90); - w = (MFloat) result.getAttr("bs"); - w.set(1); - MFloat3 wu = (MFloat3) result.getAttr("wu"); - wu.set(0, 1, 0); - MInt e = (MInt) result.getAttr("wut"); - e.set(3); - e = (MInt) result.getAttr("ua"); - e.set(2); - e = (MInt) result.getAttr("fa"); - e.set(1); - } - } - - static class MultiplyDivideType extends MNodeType { - MultiplyDivideType(MEnv env) { - super(env, "multiplyDivide"); - addSuperType(env.findNodeType("dependNode")); - /* - Operation controls the operation performed by this node. The settings are: - No operation: Output is set to equal Input 1. Input 2 is completely ignored. - Multiply: Output is set to equal Input 1 times Input 2. - - Divide: Output is set to equal Input 1 divided by Input 2. - - Power: Output is set to equal Input 1 raised to the power of Input 2. - - Tip: To calculate the square root of Input 1, set Operation to Power, and set Input 2 to 0.5 - */ - addAttribute(new MAttribute(env, "operation", "op", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "input1", "i1", - env.findDataType("float3"))); - addAlias("i1x", "i1.x"); - addAlias("i1y", "i1.y"); - addAlias("i1z", "i1.z"); - addAttribute(new MAttribute(env, "input2", "i2", - env.findDataType("float3"))); - addAlias("i2x", "i2.x"); - addAlias("i2y", "i2.y"); - addAlias("i2z", "i2.z"); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("float3"))); - addAlias("ox", "o.x"); - addAlias("oy", "o.y"); - addAlias("oz", "o.z"); - - } - - @Override - protected void initNode(MNode result) { - MInt op = (MInt) result.getAttr("op"); - op.set(1); - } - } - - static class NonAmbientLightShapeNodeType extends MNodeType { - NonAmbientLightShapeNodeType(MEnv env) { - super(env, "nonAmbientLightShapeNode"); - addSuperType(env.findNodeType("renderLight")); - addAttribute(new MAttribute(env, "decayRate", "de", - env.findDataType("enum"))); - } - } - - static class NonExtendedLightShapeNodeType extends MNodeType { - NonExtendedLightShapeNodeType(MEnv env) { - super(env, "nonExtendedLightShapeNode"); - addSuperType(env.findNodeType("nonAmbientLightShapeNode")); - } - } - - static class NurbsCurveType extends MNodeType { - NurbsCurveType(MEnv env) { - super(env, "nurbsCurve"); - addSuperType(env.findNodeType("curveShape")); - addAttribute(new MAttribute(env, "cached", "cc", - env.findDataType("nurbsCurve"))); - addAttribute(new MAttribute(env, "worldSpace", "ws", - new MArrayType(env, - env.findDataType("nurbsCurve")))); - addAttribute(new MAttribute(env, "local", "l", - env.findDataType("nurbsCurve"))); - } - } - - static class ObjectSetType extends MNodeType { - ObjectSetType(MEnv env) { - super(env, "objectSet"); - addSuperType(env.findNodeType("entity")); - /* - addAttribute(new MAttribute(env, "dnSetMembers", "dnsm", - env.findDataType("genericTypedData"))); - */ - } - } - - static class OrientConstraint extends MNodeType { - OrientConstraint(final MEnv env) { - super(env, "orientConstraint"); - addSuperType(env.findNodeType("constraint")); - addAttribute(new MAttribute(env, "target", "tg", - new MArrayType(env, - new MCompoundType(env, - "orientConstraint.tg") { - { - addField("tt", - env.findDataType("double3"), - null); - addField("trp", - env.findDataType("double3"), - null); - addField("trt", - env.findDataType("double3"), - null); - addField("tpm", - env.findDataType("matrix"), - null); - addField("tw", - env.findDataType("double"), - null); - } - }))); - } - } - - static class ParentConstraint extends MNodeType { - ParentConstraint(final MEnv env) { - super(env, "parentConstraint"); - addSuperType(env.findNodeType("constraint")); - addAttribute(new MAttribute(env, "target", "tg", - new MArrayType(env, - new MCompoundType(env, - "parentConstraint.tg") { - { - addField("tt", - env.findDataType("double3"), - null); - addField("trp", - env.findDataType("double3"), - null); - addField("trt", - env.findDataType("double3"), - null); - addField("tpm", - env.findDataType("matrix"), - null); - addField("tw", - env.findDataType("double"), - null); - } - }))); - addAttribute(new MAttribute(env, "restRotate", "rsrr", - env.findDataType("double3"))); - addAlias("rsrrx", "rsrr.x"); - addAlias("rsrry", "rsrr.y"); - addAlias("rsrrz", "rsrr.z"); - - addAttribute(new MAttribute(env, "offset", "o", - env.findDataType("double3"))); - addAlias("ox", "o.x"); - addAlias("oy", "o.y"); - addAlias("oz", "o.z"); - addAttribute(new MAttribute(env, "restTranslate", "rst", - env.findDataType("double3"))); - addAlias("rstx", "rst.x"); - addAlias("rsty", "rst.y"); - addAlias("rstz", "rst.z"); - } - } - - static class ParticleType extends MNodeType { - ParticleType(MEnv env) { - super(env, "particle"); - addSuperType(env.findNodeType("deformableShape")); - addAttribute(new MAttribute(env, "newParticles", "npt", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "lifeSpanMode", "lfm", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "lifeSpanRandom", "lfr", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "emissionToWorld", "eiw", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "inputForce", "ifc", - env.findDataType("float3[]"))); - - } - - @Override - protected void initNode(MNode result) { - MBool eiw = (MBool) result.getAttr("eiw"); - eiw.set(true); - } - } - - static class PhongENodeType extends MNodeType { - PhongENodeType(MEnv env) { - super(env, "phongE"); - addSuperType(env.findNodeType("reflect")); - addAttribute(new MAttribute(env, "cosinePower", "cp", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat cp = (MFloat) result.getAttr("cp"); - cp.set(20f); - } - } - - static class PhongNodeType extends MNodeType { - PhongNodeType(MEnv env) { - super(env, "phong"); - addSuperType(env.findNodeType("reflect")); - addAttribute(new MAttribute(env, "cosinePower", "cp", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat cp = (MFloat) result.getAttr("cp"); - cp.set(20f); - } - } - - static class Place2dTexture extends MNodeType { - Place2dTexture(final MEnv env) { - super(env, "place2dTexture"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "VertexUvOne", "vt1", - env.findDataType("float2"))); - addAlias("vt1.x", "t1u"); - addAlias("vt1.y", "t1v"); - addAttribute(new MAttribute(env, "VertexUvTwo", "vt2", - env.findDataType("float2"))); - addAlias("vt2.x", "t2u"); - addAlias("vt2.y", "t2v"); - addAttribute(new MAttribute(env, "VertexUvThree", "vt3", - env.findDataType("float2"))); - addAlias("vt3.x", "t3u"); - addAlias("vt3.y", "t3v"); - - addAttribute(new MAttribute(env, "uvCoord", "uv", - env.findDataType("float2"))); - addAlias("uv.x", "u"); - addAlias("uv.y", "v"); - } - } - - static class PlusMinusAverageType extends MNodeType { - PlusMinusAverageType(MEnv env) { - super(env, "plusMinusAverage"); - addSuperType(env.findNodeType("dependNode")); - /* - Operation controls the mathematical operation done by this node. It has four possible values: - No operation: The first input is copied to the output. All other inputs are ignored. - - Sum: All of the inputs are added together, and the output is set to their sum. - - Subtract: The output is set to the first input, minus all the other inputs. - - Average: The output is set to the sum of all the inputs, divided by the number of inputs. - */ - addAttribute(new MAttribute(env, "operation", "op", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "input1D", "i1", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "input2D", "i2", - env.findDataType("float2[]"))); - addAttribute(new MAttribute(env, "input3D", "i3", - env.findDataType("float3[]"))); - addAlias("i2x", "i2.x"); - addAlias("i2y", "i2.y"); - - addAlias("i3x", "i3.x"); - addAlias("i3y", "i3.y"); - addAlias("i3z", "i3.z"); - - addAttribute(new MAttribute(env, "output1D", "o1", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "output2D", "o2", - env.findDataType("float2"))); - addAttribute(new MAttribute(env, "output3D", "o3", - env.findDataType("float3"))); - addAlias("o2x", "o2.x"); - addAlias("o2y", "o2.y"); - - addAlias("o3x", "o3.x"); - addAlias("o3y", "o3.y"); - addAlias("o3z", "o3.z"); - - } - - @Override - protected void initNode(MNode result) { - MInt op = (MInt) result.getAttr("op"); - op.set(1); - } - } - - static class PointConstraint extends MNodeType { - PointConstraint(MEnv env) { - super(env, "pointConstraint"); - addSuperType(env.findNodeType("constraint")); - addAttribute(new MAttribute(env, "constraintRotatePivot", "crp", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "constraintRotateTranslate", "crt", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "constraintTranslate", "ct", - env.findDataType("double3"))); - - addAlias("crpx", "crp.x"); - addAlias("crpy", "crp.y"); - addAlias("crpz", "crp.z"); - - addAlias("crtx", "crt.x"); - addAlias("crty", "crt.y"); - addAlias("crtz", "crt.z"); - - addAlias("ctx", "ct.x"); - addAlias("cty", "ct.y"); - addAlias("ctz", "ct.z"); - - addAttribute(new MAttribute(env, "restTranslate", "rst", - env.findDataType("double3"))); - addAlias("rstx", "rst.x"); - addAlias("rsty", "rst.y"); - addAlias("rstz", "rst.z"); - } - } - - static class PointEmitter extends MNodeType { - PointEmitter(MEnv env) { - super(env, "pointEmitter"); - addSuperType(env.findNodeType("dynBase")); - addAttribute(new MAttribute(env, "emitterType", "emt", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "rate", "rat", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "speed", "spd", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "speedRandom", "srnd", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "direction", "d", - env.findDataType("double3"))); - addAlias("dx", "d.x"); - addAlias("dy", "d.y"); - addAlias("dz", "d.z"); - addAttribute(new MAttribute(env, "particleColor", "pc", - env.findDataType("double3"))); - addAlias("pcr", "pc.x"); - addAlias("pcg", "pc.y"); - addAlias("pcb", "pc.z"); - addAttribute(new MAttribute(env, "output", "ot", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "spread", "spr", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MInt e = (MInt) result.getAttr("emt"); - e.set(1); - MFloat d = (MFloat) result.getAttr("rat"); - d.set(100); - MFloat3 d3 = (MFloat3) result.getAttr("d"); - d3.set(1, 0, 0); - MFloat3 pc = (MFloat3) result.getAttr("pc"); - pc.set(.5f, .5f, .5f); - MFloat spd = (MFloat) result.getAttr("spd"); - spd.set(1); - } - } - - static class PointLightType extends MNodeType { - PointLightType(MEnv env) { - super(env, "pointLight"); - addSuperType(env.findNodeType("nonExtendedLightShapeNode")); - } - } - - static class PoleVectorConstraint extends MNodeType { - PoleVectorConstraint(final MEnv env) { - super(env, "poleVectorConstraint"); - addSuperType(env.findNodeType("pointConstraint")); - addAttribute(new MAttribute(env, "pivotSpace", "ps", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "target", "tg", - new MCompoundType(env, - "poleVectorConstraint.tg") { - { - addField("tt", - env.findDataType("double3"), - null); - addField("trp", - env.findDataType("double3"), - null); - addField("trt", - env.findDataType("double3"), - null); - addField("tpm", - env.findDataType("matrix"), - null); - addField("tw", - env.findDataType("double"), - null); - } - })); - } - } - - static class PolyBaseType extends MNodeType { - PolyBaseType(MEnv env) { - super(env, "polyBase"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "output", "out", - env.findDataType("Message"))); - } - } - - static class PolyCreatorType extends MNodeType { - PolyCreatorType(MEnv env) { - super(env, "polyCreator"); - addSuperType(env.findNodeType("polyBase")); - } - } - - static class PolyCubeType extends MNodeType { - PolyCubeType(MEnv env) { - super(env, "polyCube"); - addSuperType(env.findNodeType("polyPrimitive")); - addAttribute(new MAttribute(env, "width", "w", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "height", "h", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "depth", "d", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat w = (MFloat) result.getAttr("w"); - MFloat h = (MFloat) result.getAttr("h"); - MFloat d = (MFloat) result.getAttr("d"); - w.set(1); - h.set(1); - d.set(1); - } - } - - static class PolyCylinderType extends MNodeType { - PolyCylinderType(MEnv env) { - super(env, "polyCylinder"); - addSuperType(env.findNodeType("polyPrimitive")); - addAttribute(new MAttribute(env, "radius", "r", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "height", "h", - env.findDataType("float"))); - - } - - @Override - protected void initNode(MNode result) { - MFloat r = (MFloat) result.getAttr("r"); - MFloat h = (MFloat) result.getAttr("h"); - r.set(1); - h.set(2); - } - } - - static class PolyModifierType extends MNodeType { - PolyModifierType(MEnv env) { - super(env, "polyModifier"); - addSuperType(env.findNodeType("polyBase")); - addAttribute(new MAttribute(env, "inputPolymesh", "ip", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "inputComponents", "ics", - env.findDataType("componentList"))); - } - } - - static class PolyNormalType extends MNodeType { - PolyNormalType(MEnv env) { - super(env, "polyNormal"); - addSuperType(env.findNodeType("polyModifier")); - addAttribute(new MAttribute(env, "normalMode", "nm", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "userNormalMode", "unm", - env.findDataType("bool"))); - } - - @Override - protected void initNode(MNode result) { - MBool f = (MBool) result.getAttr("unm"); - f.set(true); - } - } - - static class PolyPrimitiveType extends MNodeType { - PolyPrimitiveType(MEnv env) { - super(env, "polyPrimitive"); - addSuperType(env.findNodeType("polyCreator")); - } - } - - static class PolySphereType extends MNodeType { - PolySphereType(MEnv env) { - super(env, "polySphere"); - addSuperType(env.findNodeType("polyPrimitive")); - addAttribute(new MAttribute(env, "radius", "r", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat r = (MFloat) result.getAttr("r"); - r.set(1); - } - } - - static class PsdFileTex extends MNodeType { - PsdFileTex(MEnv env) { - super(env, "psdFileTex"); - addSuperType(env.findNodeType("file")); - addAttribute(new MAttribute(env, "layerSetName", "lsn", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "layerSets", "lys", - env.findDataType("string[]"))); - addAttribute(new MAttribute(env, "alpha", "alp", - env.findDataType("string"))); - addAttribute(new MAttribute(env, "alphaList", "als", - env.findDataType("string[]"))); - } - } - - //---------------------------------------------------------------------- - // Utility node types - // - - static class RadialField extends MNodeType { - RadialField(final MEnv env) { - super(env, "radialField"); - addSuperType(env.findNodeType("field")); - addAttribute(new MAttribute(env, "radialType", "typ", - env.findDataType("double"))); - } - } - - static class ReflectType extends MNodeType { - ReflectType(MEnv env) { - super(env, "reflect"); - addSuperType(env.findNodeType("lambert")); - addAttribute(new MAttribute(env, "specularColor", "sc", - env.findDataType("float3"))); - addAlias("sr", "sc.x"); - addAlias("sg", "sc.y"); - addAlias("sb", "sc.z"); - addAttribute(new MAttribute(env, "reflectivity", "rfl", - env.findDataType("float"))); - } - - @Override - protected void initNode(MNode result) { - MFloat3 sc = (MFloat3) result.getAttr("sc"); - sc.set(.5f, .5f, .5f); - MFloat rfl = (MFloat) result.getAttr("rfl"); - rfl.set(.5f); - } - } - - static class RenderLightType extends MNodeType { - RenderLightType(MEnv env) { - super(env, "renderLight"); - addSuperType(env.findNodeType("light")); - } - } - - static class ReverseType extends MNodeType { - ReverseType(MEnv env) { - super(env, "reverse"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("float3"))); - addAlias("ix", "i.x"); - addAlias("iy", "i.y"); - addAlias("iz", "i.z"); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("float3"))); - addAlias("ox", "o.x"); - addAlias("oy", "o.y"); - addAlias("oz", "o.z"); - - } - } - - static class RigidBodyType extends MNodeType { - RigidBodyType(final MEnv env) { - super(env, "rigidBody"); - addSuperType(env.findNodeType("shape")); - addAttribute(new MAttribute(env, "inputGeometryMsg", "igm", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "initialPosition", "ip", - env.findDataType("double3"))); - addAlias("ipx", "ip.x"); - addAlias("ipy", "ip.y"); - addAlias("ipz", "ip.z"); - addAttribute(new MAttribute(env, "mass", "mas", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "bounciness", "b", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "staticFriction", "sf", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "dynamicFriction", "df", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "centerOfMass", "com", - env.findDataType("double3"))); - addAttribute(new MAttribute(env, "standin", "si", - env.findDataType("enum"))); - addAlias("cmx", "com.x"); - addAlias("cmy", "com.y"); - addAlias("cmz", "com.z"); - addAttribute(new MAttribute(env, "initialVelocity", "iv", - env.findDataType("double3"))); - addAlias("ivx", "iv.x"); - addAlias("ivy", "iv.y"); - addAlias("ivz", "iv.z"); - addAttribute(new MAttribute(env, "initialSpin", "is", - env.findDataType("double3"))); - addAlias("is.x", "is.x"); - addAlias("is.y", "is.y"); - addAlias("is.z", "is.z"); - addAttribute(new MAttribute(env, "initialOrientation", "ior", - env.findDataType("double3"))); - addAlias("iox", "ior.x"); - addAlias("ioy", "ior.y"); - addAlias("ioz", "ior.z"); - addAttribute(new MAttribute(env, "isKinematic", "kin", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "active", "act", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "fieldData", "fld", - new MCompoundType(env, - "rigidBody.fild") { - { - addField("fdp", - env.findDataType("float3[]"), - null); - addField("fdv", - env.findDataType("float3[]"), - null); - addField("fdm", - env.findDataType("float[]"), - null); - addField("dt", - env.findDataType("time"), - null); - } - })); - ; - - addAttribute(new MAttribute(env, "inputForce", "ifr", - env.findDataType("float3[]"))); - } - - @Override - protected void initNode(MNode result) { - MBool active = (MBool) result.getAttr("active"); - active.set(true); - MFloat mass = (MFloat) result.getAttr("mas"); - mass.set(1f); - MFloat staticFriction = (MFloat) result.getAttr("sf"); - staticFriction.set(.2f); - MFloat dynamicFriction = (MFloat) result.getAttr("df"); - dynamicFriction.set(.2f); - MFloat bounciness = (MFloat) result.getAttr("b"); - bounciness.set(.6f); - } - } - - static class RigidConstraint extends MNodeType { - RigidConstraint(MEnv env) { - super(env, "rigidConstraint"); - addSuperType(env.findNodeType("transform")); - - addAttribute(new MAttribute(env, "rigidBody1", "rb1", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "rigidBody2", "rb2", - new MArrayType(env, - env.findDataType("Message")))); - - addAttribute(new MAttribute(env, "constraintType", "typ", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "initialPosition", "ip", - env.findDataType("double3"))); - addAlias("ipx", "ip.x"); - addAlias("ipy", "ip.y"); - addAlias("ipz", "ip.z"); - addAttribute(new MAttribute(env, "initialOrientation", "ino", - env.findDataType("double3"))); - addAlias("iox", "inp.x"); - addAlias("ioy", "inp.y"); - addAlias("ioz", "inp.z"); - addAttribute(new MAttribute(env, "springDamping", "dmp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "springStiffness", "sst", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "springRestLength", "srl", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "choice", "chc", - env.findDataType("integer"))); - } - - @Override - protected void initNode(MNode result) { - MInt typ = (MInt) result.getAttr("typ"); - typ.set(1); - MFloat sst = (MFloat) result.getAttr("sst"); - sst.set(5); - MFloat dmp = (MFloat) result.getAttr("dmp"); - dmp.set(.1f); - MFloat srl = (MFloat) result.getAttr("srl"); - srl.set(1); - } - } - - static class ShadingEngineNodeType extends MNodeType { - ShadingEngineNodeType(MEnv env) { - super(env, "shadingEngine"); - addSuperType(env.findNodeType("objectSet")); - addAttribute(new MAttribute(env, "surfaceShader", "ss", - env.findDataType("Message"))); - } - } - - static class ShapeType extends MNodeType { - ShapeType(MEnv env) { - super(env, "shape"); - addSuperType(env.findNodeType("dagNode")); - } - } - - static class SkinClusterNodeType extends MNodeType { - SkinClusterNodeType(final MEnv env) { - super(env, "skinCluster"); - addSuperType(env.findNodeType("geometryFilter")); - addAttribute(new MAttribute(env, "weightList", "wl", - new MArrayType(env, - new MCompoundType(env, - "skinCluster.wl") { - { - addField("w", - env.findDataType("double[]"), - env.createData("double[]")); - } - }))); - addAttribute(new MAttribute(env, "bindPreMatrix", "pm", - new MArrayType(env, - env.findDataType("matrix")))); - addAttribute(new MAttribute(env, "geomMatrix", "gm", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "matrix", "ma", - new MArrayType(env, - env.findDataType("matrix")))); - } - } - - // - // End utility node types - //---------------------------------------------------------------------- - - static class SpotLightType extends MNodeType { - SpotLightType(MEnv env) { - super(env, "spotLight"); - addSuperType(env.findNodeType("nonExtendedLightShapeNode")); - addAttribute(new MAttribute(env, "coneAngle", "ca", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "penumbraAngle", "pa", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "dropoff", "dro", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MFloat ca = (MFloat) result.getAttr("ca"); - ca.set(40); - } - } - - static class SurfaceShaderType extends MNodeType { - SurfaceShaderType(MEnv env) { - super(env, "surfaceShader"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "color", "c", - env.findDataType("float3"))); - addAlias("cr", "c.x"); - addAlias("cg", "c.y"); - addAlias("cb", "c.z"); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outTransparency", "ot", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outGlowColor", "ogc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outMatteOpacity", "omo", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "diffuse", "dc", - env.findDataType("float"))); - addAttribute(new MAttribute(env, "ambientColor", "ambc", - env.findDataType("float3"))); - addAlias("acr", "ambc.x"); - addAlias("acg", "ambc.y"); - addAlias("acb", "ambc.z"); - addAttribute(new MAttribute(env, "incandescence", "ic", - env.findDataType("float3"))); - addAlias("ir", "ic.x"); - addAlias("ig", "ic.y"); - addAlias("ib", "ic.z"); - addAttribute(new MAttribute(env, "transparency", "it", - env.findDataType("float3"))); - addAlias("itr", "it.x"); - addAlias("itg", "it.y"); - addAlias("itb", "it.z"); - addAttribute(new MAttribute(env, "normalCamera", "n", - env.findDataType("float3"))); - addAlias("nx", "n.x"); - addAlias("ny", "n.y"); - addAlias("nz", "n.z"); - addAttribute(new MAttribute(env, "transparency", "it", - env.findDataType("float3"))); - addAlias("itr", "it.x"); - addAlias("itg", "it.y"); - addAlias("itb", "it.z"); - } - - @Override - protected void initNode(MNode node) { - MFloat dc = (MFloat) node.getAttr("dc"); - dc.set(.8f); - // MFloat3 ambc = (MFloat3)node.getAttr("ambc"); - // ambc.set(.2f, .2f, .2f); - MFloat3 c = (MFloat3) node.getAttr("c"); - c.set(.5f, .5f, .5f); - // MFloat3 ic = (MFloat3)node.getAttr("ic"); - - } - } - - static class SurfaceShapeType extends MNodeType { - SurfaceShapeType(MEnv env) { - super(env, "surfaceShape"); - addSuperType(env.findNodeType("controlPoint")); - } - } - - static class Texture2DType extends MNodeType { - Texture2DType(MEnv env) { - super(env, "texture2d"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "outColor", "oc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outAlpha", "oa", - env.findDataType("float"))); - } - } - - static class TransformGeometryType extends MNodeType { - TransformGeometryType(MEnv env) { - super(env, "transformGeometry"); - addSuperType(env.findNodeType("abstractBaseCreate")); - addAttribute(new MAttribute(env, "inputGeometry", "ig", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "transform", "txf", - env.findDataType("matrix"))); - addAttribute(new MAttribute(env, "invertTransform", "itf", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "freezeNormals", "fn", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "outputGeometry", "og", - env.findDataType("Message"))); - } - } - - static class TransformNodeType extends MNodeType { - TransformNodeType(MEnv env) { - super(env, "transform"); - MDataType t = env.findDataType("double3"); - addSuperType(env.findNodeType("geometryShape")); - addAttribute(new MAttribute(env, "translate", "t", t)); - addAttribute(new MAttribute(env, "rotate", "r", t)); - addAttribute(new MAttribute(env, "scale", "s", t)); - addAttribute(new MAttribute(env, "rotateAxis", "ra", t)); - addAttribute(new MAttribute(env, "rotatePivot", "rp", t)); - addAttribute(new MAttribute(env, "rotatePivotTranslate", "rpt", t)); - addAttribute(new MAttribute(env, "scalePivot", "sp", t)); - addAttribute(new MAttribute(env, "scalePivotTranslate", "spt", t)); - addAttribute(new MAttribute(env, "translateMinusRotatePivot", - "tmrp", t)); - addAttribute(new MAttribute(env, "worldMatrix", "wm", - env.findDataType("matrix"))); - String[] alias = new String[] { "t", "r", "s", "rp", "rpt", "sp", - "spt", "ra", "tmrp", }; - String[] comps = new String[] { "x", "y", "z" }; - for (String alia : alias) { - for (int j = 0; j < 3; j++) { - addAlias(alia + comps[j], alia + "[" + j + "]"); - } - } - } - - @Override - protected void initNode(MNode result) { - MFloat3 s = (MFloat3) result.getAttr("s"); - s.set(1, 1, 1); - } - } - - static class TweakNodeType extends MNodeType { - TweakNodeType(final MEnv env) { - super(env, "tweak"); - addSuperType(env.findNodeType("geometryFilter")); - } - } - - static class UnitConversionType extends MNodeType { - UnitConversionType(MEnv env) { - super(env, "unitConversion"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "input", "i", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "output", "o", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "conversionFactor", "cf", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MFloat cf = (MFloat) result.getAttr("cf"); - cf.set(1f); - } - } - - static class UvChooser extends MNodeType { - UvChooser(final MEnv env) { - super(env, "uvChooser"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "VertexUvOne", "vt1", - env.findDataType("float2"))); - addAlias("vt1.x", "t1u"); - addAlias("vt1.y", "t1v"); - addAttribute(new MAttribute(env, "VertexUvTwo", "vt2", - env.findDataType("float2"))); - addAlias("vt2.x", "t2u"); - addAlias("vt2.y", "t2v"); - addAttribute(new MAttribute(env, "VertexUvThree", "vt3", - env.findDataType("float2"))); - addAlias("vt3.x", "t3u"); - addAlias("vt3.y", "t3v"); - - addAttribute(new MAttribute(env, "outVertexUvOne", "ov1", - env.findDataType("float2"))); - addAlias("ov1.x", "o1u"); - addAlias("ov1.y", "o1v"); - addAttribute(new MAttribute(env, "outVertexUvTwo", "ov2", - env.findDataType("float2"))); - addAlias("ov2.x", "o2u"); - addAlias("ov2.y", "o2v"); - addAttribute(new MAttribute(env, "outVertexUvThree", "ov3", - env.findDataType("float2"))); - - addAlias("ov3.x", "o3u"); - addAlias("ov3.y", "o3v"); - addAttribute(new MAttribute(env, "outUv", "ouv", - env.findDataType("float2"))); - addAlias("ouv.x", "ou"); - addAlias("ouv.y", "ov"); - addAttribute(new MAttribute(env, "uvSets", "uvs", - new MArrayType(env, - env.findDataType("string")))); - } - } - - static class VortexField extends MNodeType { - VortexField(final MEnv env) { - super(env, "vortexField"); - addSuperType(env.findNodeType("field")); - addAttribute(new MAttribute(env, "axis", "ax", - env.findDataType("float3"))); - addAlias("axx", "ax.x"); - addAlias("axy", "ax.y"); - addAlias("axz", "ax.z"); - } - } - - Map> connections = new HashMap<>(); - - Map> invConnections = new HashMap<>(); - - float playbackEnd; - - float playbackStart; - - private Map dataTypes = new HashMap(); - - private Set nodes = new LinkedHashSet(); - - private Map nodeTypes = new HashMap(); - - public MEnv() { - // DATA TYPES - addDataType(new MCharacterMappingType(this)); - addDataType(new MAttributeAliasType(this)); - addDataType(new MBoolType(this)); - addDataType(new MIntType(this)); - addDataType(new MIntArrayType(this)); - addDataType(new MStringType(this)); - addDataType(new MFloatType(this)); - addDataType(new MFloat2Type(this)); - addDataType(new MFloat3Type(this)); - addDataType(new MFloatArrayType(this)); - addDataType(new MFloat2ArrayType(this)); - addDataType(new MFloat3ArrayType(this)); - addDataType(new MInt3ArrayType(this)); - addDataType(new MPointerType(this)); - addDataType(new MPolyFaceType(this)); - addDataType(new MMatrixType(this)); - addDataType(new MComponentListType(this)); - addDataType(new MNurbsCurveType(this)); - - aliasDataType("short", "int"); - aliasDataType("long", "int"); - aliasDataType("double", "float"); - aliasDataType("double[]", "float[]"); - aliasDataType("time", "float"); - aliasDataType("enum", "int"); - aliasDataType("long[]", "int[]"); - aliasDataType("enum[]", "int[]"); - aliasDataType("long3", "int3"); - aliasDataType("long3[]", "int3[]"); - aliasDataType("double2", "float2"); - aliasDataType("double3", "float3"); - aliasDataType("double3[]", "float3[]"); - aliasDataType("function", "int"); - - addDataType(new MArrayType(this, findDataType("string"))); - aliasDataType("stringArray", "string[]"); - - // NODE TYPES - addNodeType(new DagNodeType(this)); - addNodeType(new ShapeType(this)); - addNodeType(new GeometryShapeType(this)); - addNodeType(new DeformableShapeType(this)); - addNodeType(new ParticleType(this)); - addNodeType(new ControlPointType(this)); - addNodeType(new CurveShapeType(this)); - addNodeType(new NurbsCurveType(this)); - addNodeType(new SurfaceShapeType(this)); - addNodeType(new MeshNodeType(this)); - addNodeType(new RigidBodyType(this)); - - addNodeType(new TransformNodeType(this)); - - addNodeType(new DynBase(this)); - addNodeType(new Field(this)); - addNodeType(new RadialField(this)); - addNodeType(new VortexField(this)); - addNodeType(new GravityField(this)); - addNodeType(new PointEmitter(this)); - addNodeType(new RigidConstraint(this)); - - addNodeType(new Constraint(this)); - addNodeType(new PointConstraint(this)); - addNodeType(new ParentConstraint(this)); - addNodeType(new OrientConstraint(this)); - addNodeType(new AimConstraint(this)); - addNodeType(new PoleVectorConstraint(this)); - addNodeType(new IKHandle(this)); - addNodeType(new IKEffectorType(this)); - - addNodeType(new DependNodeType(this)); - addNodeType(new DagPoseType(this)); - addNodeType(new AbstractBaseCreateType(this)); - addNodeType(new TransformGeometryType(this)); - addNodeType(new PolyBaseType(this)); - addNodeType(new PolyModifierType(this)); - addNodeType(new PolyNormalType(this)); - addNodeType(new AddDoubleLinearType(this)); - addNodeType(new MotionPathType(this)); - addNodeType(new LayeredTexture(this)); - addNodeType(new UvChooser(this)); - addNodeType(new Place2dTexture(this)); - addNodeType(new ChoiceNodeType(this)); - addNodeType(new PolyBaseType(this)); - addNodeType(new PolyCreatorType(this)); - addNodeType(new PolyPrimitiveType(this)); - addNodeType(new PolyCubeType(this)); - addNodeType(new PolyCylinderType(this)); - addNodeType(new PolySphereType(this)); - - addNodeType(new Bump2dNodeType(this)); - addNodeType(new JointNodeType(this)); - addNodeType(new GeometryFilterNodeType(this)); - addNodeType(new SkinClusterNodeType(this)); - addNodeType(new BlendShapeNodeType(this)); - addNodeType(new TweakNodeType(this)); - addNodeType(new GroupIdType(this)); - addNodeType(new GroupPartsType(this)); - addNodeType(new animCurve(this)); - addNodeType(new animCurveTA(this)); - addNodeType(new animCurveTL(this)); - addNodeType(new animCurveTU(this)); - addNodeType(new animCurveUA(this)); - addNodeType(new animCurveUL(this)); - addNodeType(new animCurveUT(this)); - addNodeType(new animCurveUU(this)); - addNodeType(new SurfaceShaderType(this)); - addNodeType(new LambertType(this)); - addNodeType(new ReflectType(this)); - addNodeType(new PhongNodeType(this)); - addNodeType(new PhongENodeType(this)); - addNodeType(new BlinnNodeType(this)); - addNodeType(new Texture2DType(this)); - addNodeType(new FileType(this)); - addNodeType(new PsdFileTex(this)); - - addNodeType(new EntityType(this)); - addNodeType(new ObjectSetType(this)); - addNodeType(new ShadingEngineNodeType(this)); - addNodeType(new LightLinkerNodeType(this)); - addNodeType(new MaterialInfoNodeType(this)); - - addNodeType(new ConditionType(this)); - addNodeType(new MultiplyDivideType(this)); - addNodeType(new PlusMinusAverageType(this)); - addNodeType(new ReverseType(this)); - addNodeType(new UnitConversionType(this)); - addNodeType(new BlendType(this)); - addNodeType(new BlendColorsType(this)); - addNodeType(new BlendWeightedType(this)); - // addNodeType(new CharacterType(this)); - addNodeType(new ClampType(this)); - - addNodeType(new LightType(this)); - addNodeType(new RenderLightType(this)); - addNodeType(new NonAmbientLightShapeNodeType(this)); - addNodeType(new NonExtendedLightShapeNodeType(this)); - addNodeType(new PointLightType(this)); - addNodeType(new DirectionalLightType(this)); - addNodeType(new SpotLightType(this)); - - addNodeType(new CameraType(this)); - - addNodeType(new hwShaderType(this)); - addNodeType(new cgfxShaderType(this)); - addNodeType(new cgfxVectorType(this)); - addNodeType(new characterType(this)); - addNodeType(new animClipType(this)); - addNodeType(new clipSchedulerType(this)); - addNodeType(new clipLibraryType(this)); - - // bullet physics nodes - addNodeType(new dRigidBody(this)); - addNodeType(new dCollisionShape(this)); - addNodeType(new dHingeConstraint(this)); - addNodeType(new dNailConstraint(this)); - - // nvidia physx physics nodes - addNodeType(new nxRigidBody(this)); - } - - public void accept(Visitor visitor) { - visitor.visitEnv(this); - for (MDataType t : dataTypes.values()) { - if (t != null) { - t.accept(visitor); - } - } - for (MNodeType t : nodeTypes.values()) { - t.accept(visitor); - } - for (MNode t : nodes) { - t.accept(visitor); - } - } - - public void addDataType(MDataType dataType) { - dataTypes.put(dataType.getName(), dataType); - } - - public void addNode(MNode node) { - nodes.add(node); - } - - public void addNodeType(MNodeType nodeType) { - nodeTypes.put(nodeType.getName(), nodeType); - } - - public void aliasDataType(String alias, String type) { - dataTypes.put(alias, dataTypes.get(type)); - } - - public void connectAttr(String src, String target) { - MPath srcPath = new MPath(this, src); - MNode srcNode = srcPath.getTargetNode(); - MPath targetPath = new MPath(this, target); - MNode targetNode = targetPath.getTargetNode(); - // System.err.println("connectAttr " + src + " to " + target + " => " + srcPath + " to " + targetPath); - if (srcNode == null || targetNode == null) { - // System.err.println(" srcNode = " + srcNode + " targetNode = " + targetNode); - return; - } - // System.err.println("connectAttr " + srcPath + " to " + targetPath); - MConnection conn = new MConnection(srcPath, targetPath); - Set set = connections.get(srcNode); - if (set == null) { - set = new HashSet(); - connections.put(srcNode, set); - } - set.add(conn); - - set = invConnections.get(targetNode); - if (set == null) { - set = new HashSet(); - invConnections.put(targetNode, set); - } - set.add(conn); - } - - public MData createData(String dataType) { - MDataType type = dataTypes.get(dataType); - if (type == null) { - // System.out.println("WARNING: data type not found: " + dataType); - return null; - } - return type.createData(); - } - - public MNode createNode(MNodeType type, String name) { - if (type == null) { - return null; - } - return type.createNode(name); - } - - public MNode createNode(String typeName, String name) { - return createNode(findNodeType(typeName), name); - } - - public MPointer createPointer(MPath path) { - MPointer ptr = new MPointerImpl((MPointerType) findDataType("Message")); - ptr.setTarget(path); - return ptr; - } - - public void dump(final PrintStream ps) { - Visitor v = new Visitor() { - @Override - public void visitAttribute(MAttribute attr) { - ps.println("Attribute : " + attr); - } - - @Override - public void visitDataType(MDataType type) { - ps.println("Data type: " + type.getName()); - } - - @Override - public void visitEnv(MEnv env) { - ps.println("MEnv:"); - } - - @Override - public void visitNode(MNode node) { - ps.println("Node: " + node.getName()); - } - - @Override - public void visitNodeAttribute(MNode node, MAttribute attr, - MData value) { - ps.println("Attribute value: " + node.getName() + "." - + attr.getShortName() + " = " + value); - } - - @Override - public void visitNodeType(MNodeType type) { - ps.println("Node Type: " + type.getName()); - } - }; - accept(v); - } - - public MDataType findDataType(String name) { - return dataTypes.get(name); - } - - public MNode findNode(String name) { - if (name.indexOf('|') >= 0) { - String[] names = name.split("\\|"); - MNode result = null; - for (String n : names) { - if (n != null && n.length() > 0) { - if (result == null) { - result = findNode(n); - } else { - result = result.getChildNode(n); - } - if (result == null) { - break; - } - } - } - return result; - } - MNode result = null; - // System.out.println("find NODE... " + name); - for (MNode n : nodes) { - if (n.getName() - .equals(name)) { - // System.out.println("find node: " + name + " : " + n.getName() + " full: " + n.getFullName()); - if (result != null) { - if (n.getParentNodes() - .size() == 0) { - result = n; - } - } else { - result = n; - } - } - } - return result; - } - - public MNodeType findNodeType(String name) { - MNodeType ret = nodeTypes.get(name); - if (ret == null) { - //System.out.println("nodeTypes =" + nodeTypes); - //throw new Error("Node Type Not Found: "+ name); - // System.out.println("node type not found: " +name); - return null; - } - return ret; - } - - public Set getConnectionsFrom(MPath path) { - return getConnectionsFrom(path, true); - } - - public Set getConnectionsFrom(MPath path, - boolean checkSubPaths) { - Set result = new HashSet(); - Set conns = connections.get(path.getTargetNode()); - if (conns != null) { - for (MConnection conn : conns) { - if (checkSubPaths) { - if (path.isPrefixOf(conn.getSourcePath())) { - result.add(conn); - } - } else { - if (path.equals(conn.getSourcePath())) { - result.add(conn); - } - } - } - } - return result; - } - - public Set getConnectionsFrom(String str) { - return getConnectionsFrom(new MPath(this, str)); - } - - public Set getConnectionsFrom(String str, - boolean checkSubPaths) { - return getConnectionsFrom(new MPath(this, str), checkSubPaths); - } - - public Set getConnectionsTo(MPath path) { - return getConnectionsTo(path, true); - } - - public Set getConnectionsTo(MPath path, - boolean checkSubPaths) { - - Set result = new HashSet(); - getConnectionsTo(path, checkSubPaths, result); - return result; - } - - public Set getConnectionsTo(MPath path, boolean checkSubPaths, - Set result) { - Set conns = invConnections.get(path.getTargetNode()); - // System.err.println("Looking up connections to: " + path); - if (conns != null) { - for (MConnection conn : conns) { - // System.err.println(" Checking " + conn.getTargetPath()); - if (checkSubPaths) { - if (path.isPrefixOf(conn.getTargetPath())) { - // System.err.println(" [adding]"); - result.add(conn); - } - } else { - if (path.equals(conn.getTargetPath())) { - // System.err.println(" [adding]"); - result.add(conn); - } - } - } - } - return result; - } - - public Set getConnectionsTo(String str) { - return getConnectionsTo(new MPath(this, str)); - } - - public Set getConnectionsTo(String str, - boolean checkSubPaths) { - return getConnectionsTo(new MPath(this, str), checkSubPaths); - } - - public Set getIncomingConnections(MNode node) { - return invConnections.get(node); - } - - public Collection getNodes() { - return nodes; - } - - public Set getOutgoingConnections(MNode node) { - return connections.get(node); - } - - public Set getPathsConnectingFrom(MPath path) { - return getPathsConnectingFrom(path, true); - } - - public Set getPathsConnectingFrom(MPath path, - boolean checkSubPaths) { - Set result = new HashSet(); - Set conns = getConnectionsFrom(path, checkSubPaths); - for (MConnection conn : conns) { - result.add(conn.getTargetPath()); - } - return result; - } - - public Set getPathsConnectingFrom(String str) { - return getPathsConnectingFrom(new MPath(this, str)); - } - - public Set getPathsConnectingFrom(String str, - boolean checkSubPaths) { - return getPathsConnectingFrom(new MPath(this, str), checkSubPaths); - } - - public Set getPathsConnectingTo(MPath path) { - return getPathsConnectingTo(path, true); - } - - public Set getPathsConnectingTo(MPath path, boolean checkSubPaths) { - Set result = new HashSet(); - Set conns = getConnectionsTo(path, checkSubPaths); - for (MConnection conn : conns) { - result.add(conn.getSourcePath()); - } - return result; - } - - public Set getPathsConnectingTo(String str) { - return getPathsConnectingTo(new MPath(this, str)); - } - - public Set getPathsConnectingTo(String str, boolean checkSubPaths) { - return getPathsConnectingTo(new MPath(this, str), checkSubPaths); - } - - public float getPlaybackEnd() { - return playbackEnd; - } - - public float getPlaybackStart() { - return playbackStart; - } - - public void setPlaybackRange(float min, float max) { - playbackStart = min; - playbackEnd = max; - } -} - -// disney maya bullet plugin - -class animClipType extends MNodeType { - public animClipType(final MEnv env) { - super(env, "animClip"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "sourceStart", "ss", - env.findDataType("time"))); - - addAttribute(new MAttribute(env, "sourceEnd", "se", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "clipInstance", "ci", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "startFrame", "sf", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "enabled", "ea", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "postCycle", "ca", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "scale", "sc", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("sc"); - f.set(1); - } - -} - -class characterType extends MNodeType { - public characterType(final MEnv env) { - super(env, "character"); - addSuperType(env.findNodeType("objectSet")); - // @TODO attributes - addAttribute(new MAttribute(env, "attributeAliasList", "aal", - env.findDataType("AttributeAlias"))); - addAttribute(new MAttribute(env, "linearValues", "lv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "unitlessValues", "uv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "angularValues", "av", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "timeValues", "tv", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "unitlessClipValues", "uc", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "animationMapping", "am", - env.findDataType("characterMapping"))); - addAttribute(new MAttribute(env, "referenceMapping", "rm", - env.findDataType("characterMapping"))); - addAttribute(new MAttribute(env, "clipIndexMap", "cim", - env.findDataType("int[]"))); - addAttribute(new MAttribute(env, "timelineClipStart", "tcs", - env.findDataType("time"))); - addAttribute(new MAttribute(env, "timelineClipEnd", "tce", - env.findDataType("time"))); - - } -} - -class clipLibraryType extends MNodeType { - public clipLibraryType(final MEnv env) { - super(env, "clipLibrary"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "clipEvalList", "cel", - new MArrayType(env, - new MCompoundType(env, - "clipEvalList.cel") { - { - addField("cev", - new MArrayType(env, - new MCompoundType(env, - "clipEvalList.cel.cev") { - { - addField("cevr", // clipEval_Raw - env.findDataType("function"), - null); - } - }), - null); - } - }))); - addAttribute(new MAttribute(env, "sourceClip", "sc", - new MArrayType(env, - env.findDataType("Message")))); - - addAttribute(new MAttribute(env, "clip", "cl", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "characterData", "cd", - new MCompoundType(env, "cd") { - { - addField("cm", - env.findDataType("characterMapping"), - null); - addField("cim", - env.findDataType("int[]"), - null); - } - })); - - } -} - -class clipSchedulerType extends MNodeType { - public clipSchedulerType(final MEnv env) { - super(env, "clipScheduler"); - addSuperType(env.findNodeType("dependNode")); - addAttribute(new MAttribute(env, "clip", "cl", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "start", "st", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "sourceStart", "ss", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "sourceEnd", "se", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "scale", "sc", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "hold", "h", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "weightStyle", "ws", - env.findDataType("int[]"))); - addAttribute(new MAttribute(env, "preCycle", "cb", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "postCycle", "ca", - env.findDataType("float[]"))); - addAttribute(new MAttribute(env, "track", "tr", - env.findDataType("int[]"))); - addAttribute(new MAttribute(env, "trackState", "ts", - env.findDataType("int[]"))); - addAttribute(new MAttribute(env, "numTracks", "nt", - env.findDataType("int"))); - - } -} - -class dCollisionShape extends MNodeType { - public dCollisionShape(final MEnv env) { - super(env, "dCollisionShape"); - addAttribute(new MAttribute(env, "type", "tp", - env.findDataType("enum"))); - addAttribute(new MAttribute(env, "scale", "sc", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "outCollisionShape", "oucs", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "inShape", "insh", - env.findDataType("Message"))); - } - - @Override - protected void initNode(MNode result) { - MFloat3 f = (MFloat3) result.getAttr("sc"); - f.set(1f, 1f, 1f); - } -} - -class dHingeConstraint extends MNodeType { - public dHingeConstraint(final MEnv env) { - super(env, "dHingeConstraint"); - addAttribute(new MAttribute(env, "inRigidBodyA", "inrba", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "inRigidBodyB", "inrbb", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "damping", "dmp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "lowerLimit", "llmt", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "upperLimit", "ulmt", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "limitSoftness", "lmSo", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "biasFactor", "biFa", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "relaxationFactor", "reFa", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "rotationInA", "hgRotA", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "rotationInB", "hgRotB", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "pivotInA", "pivinA", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "pivotInB", "pivinB", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "enableAngularMotor", "enAM", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "motorTargetVelocity", "mTV", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "maxMotorImpulse", "mMI", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("reFa"); - f.set(1.0f); - f = (MFloat) result.getAttr("dmp"); - f.set(1.0f); - f = (MFloat) result.getAttr("llmt"); - f.set(1.0f); - f = (MFloat) result.getAttr("ulmt"); - f.set(-1.0f); - f = (MFloat) result.getAttr("reFa"); - f.set(1.0f); - f = (MFloat) result.getAttr("lmSo"); - f.set(.9f); - f = (MFloat) result.getAttr("biFa"); - f.set(.3f); - f = (MFloat) result.getAttr("mMI"); - f.set(1.0f); - } -} - -class dNailConstraint extends MNodeType { - public dNailConstraint(final MEnv env) { - super(env, "dNailConstraint"); - addAttribute(new MAttribute(env, "inRigidBodyA", "inrbA", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "inRigidBodyB", "inrbB", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "damping", "dmp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "pivotInA", "pivA", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "pivotInB", "pivB", - env.findDataType("float3"))); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("dmp"); - f.set(1.0f); - } -} - -class dRigidBody extends MNodeType { - public dRigidBody(final MEnv env) { - super(env, "dRigidBody"); - addAttribute(new MAttribute(env, "inCollisionShape", "incs", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "solver", "solv", - env.findDataType("Message"))); - addAttribute(new MAttribute(env, "restitution", "rst", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "friction", "fc", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "linearDamping", "ld", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "angularDamping", "ad", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "initialPosition", "inpo", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialRotation", "inro", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialVelocity", "inve", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialSpin", "insp", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "mass", "ma", - env.findDataType("double"))); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("rst"); - f.set(.1f); - f = (MFloat) result.getAttr("fc"); - f.set(0.5f); - f = (MFloat) result.getAttr("ld"); - f.set(0.3f); - f = (MFloat) result.getAttr("ad"); - f.set(0.3f); - f = (MFloat) result.getAttr("ma"); - f.set(1.0f); - } -} - -class nxRigidBody extends MNodeType { - public nxRigidBody(final MEnv env) { - super(env, "nxRigidBody"); - addAttribute(new MAttribute(env, "initialPosition", "ip", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialOrientation", "ior", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialVelocity", "iv", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "initialSpin", "is", - env.findDataType("float3"))); - addAttribute(new MAttribute(env, "staticFriction", "sf", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "dynamicFriction", "df", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "centerOfMass", "com", - env.findDataType("float3"))); - /* - addAttribute(new MAttribute(env, "inertiaTensor", "inert", - env.findDataType("float3"))); - */ - addAttribute(new MAttribute(env, "mass", "mas", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "density", "den", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "shape", "sha", - new MArrayType(env, - env.findDataType("Message")))); - addAttribute(new MAttribute(env, "active", "act", - env.findDataType("bool"))); - addAttribute(new MAttribute(env, "bounciness", "b", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "damping", "dp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "angularDamping", "adp", - env.findDataType("double"))); - addAttribute(new MAttribute(env, "sleepingThreshold", "sthrd", - env.findDataType("double"))); - - // joint orient - addAttribute(new MAttribute(env, "jointOrient", "jo", - env.findDataType("double3"))); - - // joint orient - addAlias("jox", "jo.x"); - addAlias("joy", "jo.y"); - addAlias("joz", "jo.z"); - - addAlias("ipx", "ip.x"); - addAlias("ipy", "ip.y"); - addAlias("ipz", "ip.z"); - - addAlias("iox", "ior.x"); - addAlias("ioy", "ior.y"); - addAlias("ioz", "ior.z"); - - addAlias("comx", "com.x"); - addAlias("comy", "com.y"); - addAlias("comz", "com.z"); - - addAlias("ivx", "iv.x"); - addAlias("ivy", "iv.y"); - addAlias("ivz", "iv.z"); - - addAlias("isx", "is.x"); - addAlias("isy", "is.y"); - addAlias("isz", "is.z"); - } - - @Override - protected void initNode(MNode result) { - MFloat f = (MFloat) result.getAttr("mas"); - f.set(1); - MBool b = (MBool) result.getAttr("act"); - b.set(true); - f = (MFloat) result.getAttr("b"); - f.set(.6f); - MFloat staticFriction = (MFloat) result.getAttr("sf"); - staticFriction.set(.2f); - MFloat dynamicFriction = (MFloat) result.getAttr("df"); - dynamicFriction.set(.2f); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MNode.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MNode.java deleted file mode 100644 index 9510300..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MNode.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.javafx.experiments.importers.maya.types.MArrayType; -import com.javafx.experiments.importers.maya.types.MDataType; -import com.javafx.experiments.importers.maya.values.MData; - -public class MNode extends MObject { - - List childNodes = new ArrayList(); - boolean hasLocalType = false; - MNodeType nodeType; - - List parentNodes = new ArrayList(); - - Map values = new HashMap(); - - public MNode(MEnv env, MNodeType type, String name) { - super(env, name); - this.nodeType = type; - } - - @Override - public void accept(MEnv.Visitor visitor) { - visitor.visitNode(this); - for (Map.Entry e : values.entrySet()) { - visitor.visitNodeAttribute(this, - getNodeType().getAttribute(e.getKey()), - e.getValue()); - } - } - - public void addAttr(String longName, String shortName, String dataType, - boolean isArray) { - addAttr(longName, shortName, dataType, isArray, null); - } - - public void addAttr(String longName, String shortName, String dataType, - boolean isArray, String parentAttr) { - // System.err.println("ADDING ATTR: " + longName + " " + shortName + " type= " + dataType); - MDataType t = getEnv().findDataType(dataType); - if (t == null) { - // System.out.println("CAN't FIND DATA TYPE: " +dataType); - } - if (isArray) { - t = new MArrayType(getEnv(), t); - } - if (parentAttr != null) { - MAttribute parent = getLocalType().getAttribute(parentAttr); - int index = parent.addChild(); - getLocalType().addAlias(shortName, - parent.getShortName() + "[" + index + "]"); - return; - } - getLocalType().addAttribute(new MAttribute(getEnv(), longName, - shortName, t)); - } - - public void createInstance(String instanceName) { - } - - public MData getAttr(MAttribute attribute) { - MData data = values.get(attribute.getShortName()); - if (data == null) { - if (data == null) { - if (attribute.getType() == null) { - // System.err.println("ATTRIBUTE TYPE is NULL: " + attribute); - return null; - } - data = attribute.getType() - .createData(); - } - values.put(attribute.getShortName(), data); - } - return data; - } - - public MData getAttr(String name) { - MPath path = new MPath(this, name); - // System.err.println("GET ATTR: " + getName() + " . " + name); - return path.apply(); - } - - public MData getAttrDirect(String attrName) { - MAttribute attr = getNodeType().getAttribute(attrName); - if (attr == null) { - // System.err.println("getAttrDirect: no such attr: " + attrName); - return null; - } - return getAttr(attr); - } - - public String getCanonicalName(String name) { - return getNodeType().getCanonicalName(name); - } - - public MNode getChildNode(String name) { - for (MNode node : childNodes) { - if (name.equals(node.getName())) { - return node; - } - } - return null; - } - - public List getChildNodes() { - return childNodes; - } - - /** - * Returns a list of MConnections connecting out of the given attribute, - * sorted by the source path. - */ - public List getConnectionsFrom(String attr) { - Set c = getEnv().getConnectionsFrom(new MPath(this, "." + attr)); - List result = new ArrayList<>(); - result.addAll(c); - Collections.sort(result, MConnection.SOURCE_PATH_COMPARATOR); - return result; - } - - /** - * Returns a list of MConnections connecting into the given attribute, - * sorted by the target path. - */ - public List getConnectionsTo(String attr) { - Set c = getEnv().getConnectionsTo(new MPath(this, - "." + attr)); - List result = new ArrayList(); - result.addAll(c); - Collections.sort(result, MConnection.TARGET_PATH_COMPARATOR); - return result; - } - - public void getConnectionsTo(String attr, Set result) { - getEnv().getConnectionsTo(new MPath(this, "." + attr), true, result); - } - - public String getFullName() { - String result = ""; - LinkedList path = new LinkedList(); - MNode n = this; - while (true) { - path.addFirst(n); - List p = n.getParentNodes(); - if (p.size() == 0) { - break; - } - n = p.get(0); - } - for (MNode x : path) { - result += "|"; - result += x.getName(); - } - // System.err.println("full name: " + getName() + " = " + result); - return result; - } - - public Set getIncomingConnections() { - return getEnv().getIncomingConnections(this); - } - - public MNode getIncomingConnectionToType(String fromAttr, String nodeType) { - return getIncomingConnectionToType(fromAttr, nodeType, true); - } - - public MNode getIncomingConnectionToType(String fromAttr, String nodeType, - boolean checkSubPaths) { - MNodeType t = getEnv().findNodeType(nodeType); - MPath path = new MPath(this, "." + fromAttr); - Set c = getEnv().getPathsConnectingTo(path, checkSubPaths); - for (MPath p : c) { - if (p.getTargetNode() - .isInstanceOf(t)) { - return p.getTargetNode(); - } - } - return null; - } - - public MNodeType getLocalType() { - if (!hasLocalType) { - hasLocalType = true; - final MNodeType superType = nodeType; - MNodeType localType = new MNodeType(getEnv(), getFullName()) { - { - addSuperType(superType); - } - }; - nodeType = localType; - } - return nodeType; - } - - public MNodeType getNodeType() { - return nodeType; - } - - public Set getOutgoingConnections() { - return getEnv().getOutgoingConnections(this); - } - - public MNode getOutgoingConnectionToType(String fromAttr, String nodeType) { - return getOutgoingConnectionToType(fromAttr, nodeType, true); - } - - public MNode getOutgoingConnectionToType(String fromAttr, String nodeType, - boolean checkSubPaths) { - // System.out.println("--> getOutgoingConnectionToType(" + fromAttr + ", " + nodeType + ", " + checkSubPaths + ")"); - MNodeType t = getEnv().findNodeType(nodeType); - MPath path = new MPath(this, "." + fromAttr); - Set c = getEnv().getPathsConnectingFrom(path, checkSubPaths); - for (MPath p : c) { - // System.out.println(" checking MPath " + p + " of " + c); - if (p.getTargetNode() - .isInstanceOf(t)) { - return p.getTargetNode(); - } - } - return null; - } - - public List getParentNodes() { - return parentNodes; - } - - /** Returns a list of MPaths connecting out of the given attribute. */ - public List getPathsConnectingFrom(String attr) { - Set c = getEnv().getPathsConnectingFrom(new MPath(this, - "." + attr)); - List result = new ArrayList(); - result.addAll(c); - return result; - } - - /** Returns a list of MPaths connecting into the given attribute. */ - public List getPathsConnectingTo(String attr) { - Set c = getEnv().getPathsConnectingTo(new MPath(this, - "." + attr)); - List result = new ArrayList(); - result.addAll(c); - return result; - } - - public boolean isInstanceOf(MNodeType t) { - return t.isAssignableFrom(getNodeType()); - } - - public void parent(MNode parent) { - parentNodes.add(parent); - } - - public void setAttr(MAttribute attr, MData value) { - if (getNodeType().getAttribute(attr.getName()) != attr) { - // System.err.println("WARNING: attribute " +attr.getName()+" not found in type: " + getNodeType().getName()); - } - setAttr(attr.getShortName(), value); - } - - public void setAttr(String name, MData value) { - if (getNodeType().getAttribute(name) == null) { - // System.err.println("WARNING: attribute " +name+" not found in type: " + getNodeType().getName()); - } - // System.err.println("setAttr + " + getName() + " " + value); - values.put(name, value); - } - - public void setParentNode(MNode n) { - parentNodes.add(n); - n.childNodes.add(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MNodeType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MNodeType.java deleted file mode 100644 index b5c6c1d..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MNodeType.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public abstract class MNodeType extends MObject { - Map attributes = new HashMap(); - Map attributesByShortName = new HashMap(); - Map canonicalNames = new HashMap(); - - List superTypes = new ArrayList(); - - public MNodeType(MEnv env, String name) { - super(env, name); - } - - @Override - public void accept(MEnv.Visitor visitor) { - visitor.visitNodeType(this); - for (MAttribute attr : attributes.values()) { - attr.accept(visitor); - } - } - - public void addAlias(String alias, String target) { - canonicalNames.put(alias, target); - } - - public void addAttribute(MAttribute attribute) { - attribute.declaringNodeType = this; - attributes.put(attribute.getName(), attribute); - attributesByShortName.put(attribute.getShortName(), attribute); - } - - public void addSuperType(MNodeType superType) { - superTypes.add(superType); - } - - public MNode createNode(String name) { - MNode n = doCreateNode(name); - getEnv().addNode(n); - doInitNode(n); - return n; - } - - public String getAlias(String name) { - for (Map.Entry e : canonicalNames.entrySet()) { - if (e.getValue() - .equals(name)) { - return e.getKey(); - } - } - for (MNodeType type : superTypes) { - String alias = type.getAlias(name); - if (alias != null) { - return alias; - } - } - // no alias - return name; - } - - public MAttribute getAttribute(String name) { - MAttribute attr = attributes.get(name); - if (attr == null) { - attr = attributesByShortName.get(name); - } - if (attr == null) { - for (MNodeType t : superTypes) { - attr = t.getAttribute(name); - if (attr != null) { - break; - } - } - } - if (attr == null) { - String canonicalName = getCanonicalName(name); - if (!canonicalName.equals(name)) { - attr = getAttribute(canonicalName); - } - } - return attr; - } - - public Collection getAttributes() { - return attributes.values(); - } - - // By convention we map names down to the short name during the - // canonicalization process. We assume that aliases are specified - // to map to short names. - public String getCanonicalName(String name) { - String tmpName = toShortName(name); - String result = getCanonicalNameRecursive(name); - if (result != null) { - return result; - } - return tmpName; - } - - public List getSuperTypes() { - return superTypes; - } - - public boolean isAssignableFrom(MNodeType other) { - if (other == this) { - return true; - } - for (MNodeType t : other.getSuperTypes()) { - if (isAssignableFrom(t)) { - return true; - } - } - return false; - } - - protected MNode doCreateNode(String name) { - return new MNode(getEnv(), this, name); - } - - protected void initNode(MNode node) { - } - - void doInitNode(MNode node) { - for (MNodeType i : superTypes) { - i.doInitNode(node); - } - initNode(node); - } - - private String getCanonicalNameRecursive(String name) { - String tmpName = toShortName(name); - String result = canonicalNames.get(tmpName); - if (result == null) { - for (MNodeType t : superTypes) { - if (t == null) { - System.out.println("missing supertype for " + getName()); - } - result = t.getCanonicalNameRecursive(name); - if (result != null) { - return result; - } - } - } - return result; - } - - private String toShortName(String name) { - MAttribute attr = attributes.get(name); - if (attr != null) { - return attr.getShortName(); - } - return name; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MObject.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MObject.java deleted file mode 100644 index c62e3a2..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MObject.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -public abstract class MObject { - MEnv env; - final String name; - - public MObject(MEnv env, String name) { - this.env = env; - this.name = name; - } - - public abstract void accept(MEnv.Visitor visitor); - - public MEnv getEnv() { - return env; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return super.toString() + " MObject.name: " + name; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MPath.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MPath.java deleted file mode 100644 index 033f65b..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MPath.java +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import java.util.ArrayList; -import java.util.List; - -import com.javafx.experiments.importers.maya.values.MArray; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat2Array; -import com.javafx.experiments.importers.maya.values.MFloat3Array; -import com.javafx.experiments.importers.maya.values.MFloatArray; -import com.javafx.experiments.importers.maya.values.MInt3Array; -import com.javafx.experiments.importers.maya.values.MIntArray; - -// ry => r[1]; - -public class MPath implements Comparable { - - static abstract class Component implements Comparable { - public MData apply(MData data) { - return null; - } - - public MData apply(MNode node) { - return null; - } - } - - // Index < Slice < Select in ordering - - static class Index extends Component { - int index; - - public Index(int i) { - index = i; - } - - @Override - public MData apply(MData data) { - data.setSize(index + 1); - return data.getData(index); - } - - @Override - public int compareTo(Object arg) { - if (arg instanceof Index) { - return index - ((Index) arg).index; - } - - if (arg instanceof Component) { - return -1; - } - - throw new ClassCastException(arg.getClass() - .getName()); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof Index)) { - return false; - } - return index == ((Index) other).index; - } - - public int getIndex() { - return index; - } - - @Override - public int hashCode() { - return 11 + 17 * index; - } - - @Override - public String toString() { - return "[" + index + "]"; - } - } - - static class Select extends Component { - String name; - - public Select(String n) { - name = n; - } - - @Override - public MData apply(MData data) { - return data.getData(name); - } - - @Override - public MData apply(MNode node) { - return node.getAttrDirect(name); - } - - @Override - public int compareTo(Object arg) { - if (arg instanceof Select) { - return name.compareTo(((Select) arg).name); - } - - if (arg instanceof Component) { - return 1; - } - - throw new ClassCastException(arg.getClass() - .getName()); - } - - @Override - public boolean equals(Object arg) { - if (!(arg instanceof Select)) { - return false; - } - Select other = (Select) arg; - return (name.equals(other.name)); - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return "." + name; - } - } - - static class Slice extends Component { - int start, end; - - public Slice(int i, int j) { - start = i; - end = j; - } - - @Override - public MData apply(MData data) { - data.setSize(end + 1); - return data.getData(start, end); - } - - @Override - public int compareTo(Object arg) { - if (arg instanceof Slice) { - Slice other = (Slice) arg; - int diff = start - other.start; - if (diff != 0) { - return diff; - } - return end - other.end; - } - - if (arg instanceof Index) { - return 1; - } - - if (arg instanceof Select) { - return -1; - } - - throw new ClassCastException(arg.getClass() - .getName()); - } - - @Override - public boolean equals(Object arg) { - if (!(arg instanceof Slice)) { - return false; - } - Slice other = (Slice) arg; - return (start == other.start && end == other.end); - } - - @Override - public int hashCode() { - return 11 + 17 * start + 23 * end; - } - - @Override - public String toString() { - return "[" + start + ":" + end + "]"; - } - } - - MAttribute attr; - - int attributeOffset = -1; - - List components = new ArrayList(); - - // A Path always exists within the context of a given node - MNode node; - - public MPath(MEnv env, String path) { - String nodeName; - int i = path.indexOf("."); - if (i > 0) { - nodeName = path.substring(0, i); - path = path.substring(i); - } else { - nodeName = path; - } - node = env.findNode(nodeName); - if (i > 0) { - addComponents(path); - } - } - - public MPath(MNode node, String path) { - this.node = node; - addComponents(path); - } - - // For copying - private MPath(MNode node) { - this.node = node; - } - - public MData apply() { - if (components.size() == 0) { - return null; - } - MData data = components.get(0) - .apply(node); - return apply(1, data); - } - - @Override - public int compareTo(Object arg) { - MPath other = (MPath) arg; - if (node != other.node) { - return node.hashCode() - other.node.hashCode(); - } - int sz = Math.min(components.size(), other.components.size()); - for (int i = 0; i < sz; i++) { - int diff = components.get(i) - .compareTo(other.components.get(i)); - if (diff != 0) { - return diff; - } - } - if (components.size() != other.components.size()) { - return components.size() - other.components.size(); - } - return 0; - } - - @Override - public boolean equals(Object arg) { - if (!(arg instanceof MPath)) { - return false; - } - MPath other = (MPath) arg; - return (node == other.node && components.equals(other.components)); - } - - public String getComponentSelector() { - int i = 0; - String result = ""; - while (i < components.size()) { - result += components.get(i) - .toString(); - i++; - } - return result.substring(1); - } - - public String getLastNamedPathComponent() { - for (int i = components.size() - 1; i >= 0; --i) { - Component comp = components.get(i); - if (comp instanceof Select) { - return comp.toString(); - } - } - return null; - } - - public String getLastPathComponent() { - return getPathComponent(components.size() - 1); - } - - public int getLastPathIndex() { - Component component = components.get(components.size() - 1); - if (component instanceof Index) { - return ((Index) component).getIndex(); - } - return -1; - } - - public String getLastSelectionPathComponent() { - for (int i = components.size() - 1; i >= 0; --i) { - Component comp = components.get(i); - if (comp instanceof Select) { - String res = ""; - for (int j = i; j < components.size(); j++) { - res += getPathComponent(j); - } - return res; - } - } - return null; - } - - /** - * Returns the parent path of this one -- i.e., the path with the last - * component removed. - */ - public MPath getParentPath() { - MPath res = new MPath(node); - for (int i = 0; i < components.size() - 1; i++) { - res.add(components.get(i)); - } - return res; - } - - public String getPathComponent(int i) { - return components.get(i) - .toString(); - } - - public MAttribute getTargetAttribute(MEnv env) { - _getAttributeOffset(); - return attr; - } - - public MNode getTargetNode() { - return node; - } - - @Override - public int hashCode() { - int hashCode = 0; - for (Component comp : components) { - hashCode += 17 * comp.hashCode(); - } - return hashCode; - /* - if (node == null) { - return 0; - } - return node.hashCode(); - */ - } - - /** Indicates whether this path is a prefix of the given one. */ - public boolean isPrefixOf(MPath other) { - if (node != other.node) { - return false; - } - if (components.size() > other.components.size()) { - return false; - } - for (int i = 0; i < components.size(); i++) { - if (!(components.get(i) - .equals(other.components.get(i)))) { - return false; - } - } - return true; - } - - public boolean isValid() { - return getTargetNode() != null; - } - - public int size() { - return components.size(); - } - - @Override - public String toString() { - if (node == null) { - return "[invalid path -- no node]"; - } else { - return node.getFullName() + components.toString(); - } - } - - int _getAttributeOffset() { - if (attributeOffset == -1) { - String selector = ""; - int i = 0; - while (i < components.size()) { - selector += components.get(i) - .toString(); - attr = getTargetNode().getNodeType() - .getAttribute(selector.substring(1)); - if (attr != null) { - attributeOffset = i; - break; - } - i++; - } - } - return attributeOffset; - } - - private void add(Component comp) { - components.add(comp); - } - - private void addComponents(String path) { - if (node == null) { - return; - } - int mark = 0; - int i = 0; - int len = path.length(); - for (; i < len; i++) { - char ch = path.charAt(i); - if (ch == '.') { - if (i - mark > 0) { - String str = path.substring(mark, i); - String str1 = canonicalize(str); - if (str.equals(str1)) { - // Before performing component selection, - // canonicalize connections to arrays to point - // to the zeroth array index - if (selectsArray()) { - add(new Index(0)); - } - add(new Select(str1)); - } else { - addComponents(str1); - } - } - mark = i + 1; - } else if (ch == '[') { - if (i - mark > 0) { - String str = path.substring(mark, i); - String str1 = canonicalize(str); - if (str.equals(str1)) { - // Before performing component selection, - // canonicalize connections to arrays to point - // to the zeroth array index - if (selectsArray()) { - add(new Index(0)); - } - add(new Select(str1)); - } else { - addComponents(str1); - } - } - int j = i + 1; - while (true) { - ch = path.charAt(j); - if (ch == ']') { - break; - } - j++; - } - String indexStr = path.substring(i + 1, j); - int colon = indexStr.indexOf(':'); - if (colon > 0) { - int start = Integer.parseInt(indexStr.substring(0, colon)); - int end = Integer.parseInt(indexStr.substring(colon + 1)); - add(new Slice(start, end)); - } else { - int index = Integer.parseInt(indexStr); - add(new Index(index)); - } - i = j + 1; - if (i < len && path.charAt(i) == '.') { - i++; - } - mark = i; - } - } - if (mark < len && i - mark > 0) { - String str = path.substring(mark, i); - String str1 = canonicalize(str); - if (str.equals(str1)) { - // Before performing component selection, - // canonicalize connections to arrays to point - // to the zeroth array index - if (selectsArray()) { - add(new Index(0)); - } - add(new Select(str1)); - } else { - addComponents("." + str1); - } - } - } - - private MData apply(int i, MData data) { - while (i < components.size()) { - if (data == null) { - return null; - } - data = components.get(i++) - .apply(data); - } - return data; - } - - private String canonicalize(String name) { - // FIXME: do we need to do this for deeper data types too? - return node.getCanonicalName(name); - } - - // Used to canonicalize for example in Mesh: - // .iog.og[n] -> .iog[0].og[n] - private boolean selectsArray() { - if (components.size() == 0) { - return false; - } - // If we're already doing an array indexing as the last - // operation in the path, state that we aren't selecting an - // array - if (components.get(components.size() - 1) instanceof Index) { - return false; - } - MData data = apply(); - if (data == null) { - return false; - } - // Should we be using MDataType instead for these type queries? - return ((data instanceof MArray) || (data instanceof MFloatArray) - || (data instanceof MFloat2Array) - || (data instanceof MFloat3Array) || (data instanceof MIntArray) - || (data instanceof MInt3Array)); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaAnimationCurveInterpolator.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MayaAnimationCurveInterpolator.java deleted file mode 100644 index f7834d4..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaAnimationCurveInterpolator.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya; - -import javafx.animation.Interpolator; - -/** - * MayaAnimationCurveInterpolator - *

- * Interpolator is from javafx.animation - */ -class MayaAnimationCurveInterpolator extends Interpolator { - - public String debug; // hack - float p1Delta; - float p2Delta; - boolean zeroDuration; - - //========================================================================= - // MayaAnimationCurveInterpolator - //========================================================================= - public MayaAnimationCurveInterpolator(float p1Delta, float p2Delta, - boolean zeroDuration) { - this.p1Delta = p1Delta; - this.p2Delta = p2Delta; - this.zeroDuration = zeroDuration; - } - - //========================================================================= - // MayaAnimationCurveInterpolator.curve - //========================================================================= - @Override - public double curve(double t) { - return t; - } - - //========================================================================= - // MayaAnimationCurveInterpolator.interpolate - //========================================================================= - // [!] API Change - public double interpolate2(double startValue, double endValue, - double fraction) { - if (Double.isNaN(fraction)) { - return startValue; - } - if (zeroDuration) { - return endValue; - } - float t = (float) fraction; - float oneMinusT = 1.0f - t; - float tSquared = t * t; - float oneMinusTSquared = oneMinusT * oneMinusT; - float p0 = (float) startValue; - float p3 = (float) endValue; - float p1 = p0 + p1Delta; - float p2 = p3 + p2Delta; - float ret = ((oneMinusTSquared * oneMinusT * p0) - + (3 * oneMinusTSquared * t * p1) - + (3 * oneMinusT * tSquared * p2) + (tSquared * t * p3)); - - if (debug != null) { - // if (DEBUG) System.out.println("interpolate: " + debug + ": " + t + " " + startValue + " to " + endValue + ": "+ret); - } - - return ret; - } - - //========================================================================= - // MayaAnimationCurveInterpolator.interpolate - //========================================================================= - // [!] API Change - public int interpolate2(int startValue, int endValue, double fraction) { - return (int) interpolate((double) startValue, (double) endValue, - fraction); - } - - //========================================================================= - // MayaAnimationCurveInterpolator.interpolate - //========================================================================= - // [!] API Change - public Object interpolate2(Object startValue, Object endValue, - double fraction) { - return interpolate(((Number) startValue).doubleValue(), - ((Number) endValue).doubleValue(), fraction); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaGroup.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MayaGroup.java deleted file mode 100644 index 112dbf7..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaGroup.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import javafx.scene.Group; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Translate; - -/** - * MayaGroup - A MayaGroup is equivalent to a Maya Transform Node - *

- * If you are post-multiplying matrices, To transform a point p from - * object-space to world-space you would need to post-multiply by the - * worldMatrix. (p' = p * wm) matrix = - * [SP-1][S][SH][SP][ST][RP-1][RA][R][RP][RT][T] where R = [RX][RY][RZ] (Note: - * order is determined by rotateOrder) - *

- * If you are pre-multiplying matrices, to transform a point p from object-space - * to world-space you would need to pre-multiply by the worldMatrix. (p' = wm * - * p) matrix = [T][RT][RP][R][RA][RP-1][ST][SP][SH][S][SP-1] where R = - * [RZ][RY][RX] (Note: order is determined by rotateOrder) Of these sub-matrices - * we can set [RT], [RA], [ST], and [SH] to identity, so matrix = - * [T][RP][R][RP-1][SP][S][SP-1] matrix = [T][RP][RZ][RY][RX][RP-1][SP][S][SP-1] - */ -public class MayaGroup extends Group { - Translate rp = new Translate(); // rotate pivot - Translate rpi = new Translate(); // rotate pivot inverse - Translate rpt = new Translate(); // rotate pivot translate - Rotate rx = new Rotate(0, Rotate.X_AXIS); - Rotate ry = new Rotate(0, Rotate.Y_AXIS); - Rotate rz = new Rotate(0, Rotate.Z_AXIS); - Scale s = new Scale(); - - Translate sp = new Translate(); // scale pivot - Translate spi = new Translate(); // scale pivot inverse - // should bind rpi = -rp, but doesn't currently work afaict - Translate spt = new Translate(); // scale pivot translate - - Translate t = new Translate(); - - public MayaGroup() { - initTransforms(); - } - - /** - * Creates mayaGroup with the same set of transforms as given mayaGroup. - * Children are not copied. - * - * @param mayaGroup - */ - public MayaGroup(MayaGroup mayaGroup) { - t = mayaGroup.t.clone(); - rpt = mayaGroup.rpt.clone(); - rp = mayaGroup.rp.clone(); - rpi = mayaGroup.rpi.clone(); - sp = mayaGroup.sp.clone(); - spi = mayaGroup.spi.clone(); - - rx = mayaGroup.rx.clone(); - ry = mayaGroup.ry.clone(); - rz = mayaGroup.rz.clone(); - - s = mayaGroup.s.clone(); - - setId(mayaGroup.getId()); - setDepthTest(mayaGroup.getDepthTest()); - setVisible(mayaGroup.isVisible()); - - initTransforms(); - } - - private void initTransforms() { - getTransforms().setAll(t, rpt, rp, rz, ry, rx, rpi, spt, sp, s, spi); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaImporter.java b/gui/src/main/java/com/javafx/experiments/importers/maya/MayaImporter.java deleted file mode 100644 index e849010..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/MayaImporter.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya; - -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.javafx.experiments.importers.Importer; - -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.scene.DepthTest; -import javafx.scene.Node; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; - -/** - * MayaImporter - *

- * MayaImporter.getRoot() returns a JavaFX node hierarchy - * MayaImporter.getTimeline() returns a JavaFX timeline - */ -public class MayaImporter extends Importer { - public static final boolean DEBUG = Loader.DEBUG; - public static final boolean WARN = Loader.WARN; - - Set meshParents = new HashSet(); - // NO_JOINTS - // [Note to Alex]: I've re-enabled joints, but lets not use rootCharacter [John] - // javafx.scene.shape3d.Character rootCharacter = new javafx.scene.shape3d.Character(); - MayaGroup root = new MayaGroup(); - Timeline timeline; - - // NO_JOINTS - // [Note to Alex]: I've re-enabled joints, but lets not use rootCharacter [John] - // public javafx.scene.shape3d.Character getRootCharacter() { - // return rootCharacter; - // } - - //========================================================================= - // MayaImporter.getMeshParents - //========================================================================= - public Set getMeshParents() { - return meshParents; - } - - @Override - public MayaGroup getRoot() { - return root; - } - - //========================================================================= - // MayaImporter.getTimeline - //------------------------------------------------------------------------- - // MayaImporter.getTimeline() returns a JavaFX timeline - // (javafx.animation.Timeline) - //========================================================================= - @Override - public Timeline getTimeline() { - return timeline; - } - - @Override - public boolean isSupported(String extension) { - return extension != null && extension.equals("ma"); - } - - //========================================================================= - // MayaImporter.load - //========================================================================= - @Override - public void load(String url, boolean asPolygonMesh) { - try { - Loader loader = new Loader(); - loader.load(new java.net.URL(url), asPolygonMesh); - - // This root is not automatically added to the scene. - // It needs to be added by the user of MayaImporter. - // root = new Xform(); - - // Add top level nodes to the root - @SuppressWarnings("unused") - int nodeCount = 0; - for (Node n : loader.loaded.values()) { - if (n != null) { - // Only add a node if it has no parents, ie. top level node - if (n.getParent() == null) { - if (Loader.DEBUG) { - System.out.println("Adding top level node " - + n.getId() + " to root!"); - } - n.setDepthTest(DepthTest.ENABLE); - if (!(n instanceof MeshView) - || ((TriangleMesh) ((MeshView) n).getMesh()).getPoints() - .size() > 0) { - root.getChildren() - .add(n); - } - } - nodeCount++; - } - } - // [Note to Alex]: I've re-enabled joints, but lets not use rootCharacter [John] - // rootCharacter.setRootJoint(loader.rootJoint); - if (Loader.DEBUG) { - System.out.println("There are " + nodeCount + " nodes."); - } - - // if meshes were not loaded in the code above - // (which they now are) one would need to - // set meshParents from the loader - // meshParents.addAll(loader.meshParents.keySet()); - // this is not necessary at the moment - - timeline = new Timeline(); - @SuppressWarnings("unused") - int count = 0; - - // Add all the keyframes to the timeline from loader.keyFrameMap - for (final Map.Entry> e : loader.keyFrameMap.entrySet()) { - // if (DEBUG) System.out.println("key frame at : "+ e.getKey()); - timeline.getKeyFrames() - .add(new KeyFrame(javafx.util.Duration.millis(e.getKey() - * 1000f), - e.getValue() - .toArray(new KeyValue[e.getValue() - .size()]))); - count++; - } - - if (Loader.DEBUG) { - System.out.println("Loaded " + count + " key frames."); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/Xform.java b/gui/src/main/java/com/javafx/experiments/importers/maya/Xform.java deleted file mode 100644 index bbf3827..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/Xform.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya; - -import javafx.scene.Group; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Translate; - -public class Xform extends Group { - - public enum RotateOrder { - XYZ, - XZY, - YXZ, - YZX, - ZXY, - ZYX - } - - public Translate ip = new Translate(); - public Translate p = new Translate(); - public Rotate rx = new Rotate(); - public Rotate ry = new Rotate(); - - public Rotate rz = new Rotate(); - - public Scale s = new Scale(); - - public Translate t = new Translate(); - - { - rx.setAxis(Rotate.X_AXIS); - } - - { - ry.setAxis(Rotate.Y_AXIS); - } - - { - rz.setAxis(Rotate.Z_AXIS); - } - - public Xform() { - super(); - getTransforms().addAll(t, rz, ry, rx, s); - } - - public Xform(RotateOrder rotateOrder) { - super(); - // choose the order of rotations based on the rotateOrder - switch (rotateOrder) { - case XYZ: - getTransforms().addAll(t, p, rz, ry, rx, s, ip); - break; - case XZY: - getTransforms().addAll(t, p, ry, rz, rx, s, ip); - break; - case YXZ: - getTransforms().addAll(t, p, rz, rx, ry, s, ip); - break; - case YZX: - getTransforms().addAll(t, p, rx, rz, ry, s, ip); // For Camera - break; - case ZXY: - getTransforms().addAll(t, p, ry, rx, rz, s, ip); - break; - case ZYX: - getTransforms().addAll(t, p, rx, ry, rz, s, ip); - break; - } - } - - public void debug() { - System.out.println("t = (" + t.getX() + ", " + t.getY() + ", " - + t.getZ() + ") " + "r = (" + rx.getAngle() + ", " - + ry.getAngle() + ", " + rz.getAngle() + ") " - + "s = (" + s.getX() + ", " + s.getY() + ", " - + s.getZ() + ") " + "p = (" + p.getX() + ", " - + p.getY() + ", " + p.getZ() + ") " + "ip = (" - + ip.getX() + ", " + ip.getY() + ", " + ip.getZ() - + ")"); - } - - public void reset() { - t.setX(0.0); - t.setY(0.0); - t.setZ(0.0); - rx.setAngle(0.0); - ry.setAngle(0.0); - rz.setAngle(0.0); - s.setX(1.0); - s.setY(1.0); - s.setZ(1.0); - p.setX(0.0); - p.setY(0.0); - p.setZ(0.0); - ip.setX(0.0); - ip.setY(0.0); - ip.setZ(0.0); - } - - public void resetTSP() { - t.setX(0.0); - t.setY(0.0); - t.setZ(0.0); - s.setX(1.0); - s.setY(1.0); - s.setZ(1.0); - p.setX(0.0); - p.setY(0.0); - p.setZ(0.0); - ip.setX(0.0); - ip.setY(0.0); - ip.setZ(0.0); - } - - public void setPivot(double x, double y, double z) { - p.setX(x); - p.setY(y); - p.setZ(z); - ip.setX(-x); - ip.setY(-y); - ip.setZ(-z); - } - - public void setRotate(double x, double y, double z) { - rx.setAngle(x); - ry.setAngle(y); - rz.setAngle(z); - } - - public void setRotateX(double x) { - rx.setAngle(x); - } - - public void setRotateY(double y) { - ry.setAngle(y); - } - - public void setRotateZ(double z) { - rz.setAngle(z); - } - - public void setRx(double x) { - rx.setAngle(x); - } - - public void setRy(double y) { - ry.setAngle(y); - } - - public void setRz(double z) { - rz.setAngle(z); - } - - public void setScale(double scaleFactor) { - s.setX(scaleFactor); - s.setY(scaleFactor); - s.setZ(scaleFactor); - } - - public void setScale(double x, double y, double z) { - s.setX(x); - s.setY(y); - s.setZ(z); - } - - // Cannot override these methods as they are final: - // public void setScaleX(double x) { s.setX(x); } - // public void setScaleY(double y) { s.setY(y); } - // public void setScaleZ(double z) { s.setZ(z); } - // Use these methods instead: - public void setSx(double x) { - s.setX(x); - } - - public void setSy(double y) { - s.setY(y); - } - - public void setSz(double z) { - s.setZ(z); - } - - public void setTranslate(double x, double y) { - t.setX(x); - t.setY(y); - } - - public void setTranslate(double x, double y, double z) { - t.setX(x); - t.setY(y); - t.setZ(z); - } - - // Cannot override these methods as they are final: - // public void setTranslateX(double x) { t.setX(x); } - // public void setTranslateY(double y) { t.setY(y); } - // public void setTranslateZ(double z) { t.setZ(z); } - // Use these methods instead: - public void setTx(double x) { - t.setX(x); - } - - public void setTy(double y) { - t.setY(y); - } - - public void setTz(double z) { - t.setZ(z); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/parser/MParser.java b/gui/src/main/java/com/javafx/experiments/importers/maya/parser/MParser.java deleted file mode 100644 index cacf4a6..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/parser/MParser.java +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya.parser; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.StringTokenizer; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.MNode; -import com.javafx.experiments.importers.maya.MPath; -import com.javafx.experiments.importers.maya.MayaImporter; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MPointer; - -public class MParser { - - // Maya-specific tokenizer; handles quoted strings with spaces and strips quotes from them - // Does not properly unescape contents of strings yet - class Tokenizer { - private boolean escaping = false; - private String line; - private int pos; - - Tokenizer(String line) { - this.line = line; - } - - public boolean hasMoreTokens() { - while (pos < line.length()) { - if (Character.isWhitespace(line.charAt(pos))) { - ++pos; - } else { - return true; - } - } - return false; - } - - public String nextToken() { - // Skip leading whitespace - while (pos < line.length() - && Character.isWhitespace(line.charAt(pos))) { - ++pos; - } - - int startPos = pos; - boolean firstChar = true; - boolean insideString = false; - - while (true) { - if (pos == line.length()) { - if ((pos - startPos) == 0) { - return null; - } else { - return line.substring(startPos, pos); - } - } - - char ch = line.charAt(pos); - if (Character.isWhitespace(ch)) { - if (!insideString) { - return line.substring(startPos, pos); - } - } else if (ch == '\"') { - if (firstChar) { - insideString = true; - // Skip quote - ++startPos; - } else if (insideString && !escaping) { - ++pos; - return line.substring(startPos, pos - 1); - } - escaping = false; - } else if (ch == '\\') { - escaping = true; - } - firstChar = false; - ++pos; - } - } - } - - private List curArgs; - private String curCommand; - private MEnv env; - private boolean inPlaybackScriptNode = false; - - private URL inputSource; - - private int lineNo; - - private Set refs = new HashSet<>(); - - private MNode selectedNode; - - public MParser(MEnv env) { - this.env = env; - } - - public void parse(InputStream inputStream) throws IOException { - BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - String line; - lineNo = 0; - List command = new ArrayList<>(); - while ((line = reader.readLine()) != null) { - ++lineNo; - Tokenizer tokenizer = new Tokenizer(line); - while (tokenizer.hasMoreTokens()) { - String tok = tokenizer.nextToken(); - if (tok.startsWith("//")) { - // Comment until end of line - break; - } - if (tok.endsWith(";")) { - // End of current command; execute it - String tmp = tok.substring(0, tok.length() - 1); - if (tmp.length() > 0) { - command.add(tmp); - } - if (command.size() > 0) { - execute(command); - command.clear(); - } - } else { - command.add(tok); - } - } - } - } - - public void parse(URL url) throws IOException { - if (url == null) { - throw new IOException("Null URL"); - } - this.inputSource = url; - URLConnection conn = url.openConnection(); - try (InputStream input = conn.getInputStream()) { - parse(input); - } - } - - private void doAddAttr() { - if (selectedNode == null) { - return; - } - String longName = null; - String shortName = null; - String dataType = null; - String attrType = null; - boolean isArray = false; - String dataValue = null; - String attrParent = null; - for (int i = 0; i < curArgs.size(); i++) { - String arg = curArgs.get(i); - switch (arg) { - case "-at": - case "-attributeType": - attrType = curArgs.get(++i); - break; - case "-p": - attrParent = curArgs.get(++i); - break; - case "-dt": - case "-dataType": - dataType = curArgs.get(++i); - break; - case "-sn": - case "-shortName": - shortName = curArgs.get(++i); - break; - case "-ln": - case "-longName": - longName = curArgs.get(++i); - break; - case "-dv": - case "-datavValue": - dataValue = curArgs.get(++i); - break; - } - } - String type = dataType != null ? dataType : attrType; - switch (type) { - case "stringArray": - type = "string[]"; - break; - case "doubleArray": - type = "double[]"; - break; - case "Int32Array": - type = "int[]"; - break; - case "fltMatrix": - type = "matrix"; - break; - case "message": - type = "Message"; - break; - case "doubleAngle": - type = "double"; - break; - case "doubleLinear": - type = "double"; - break; - default: - // TBD... or add all these as type aliases to env... - break; - } - selectedNode.addAttr(longName, shortName, type, isArray, attrParent); - if (dataValue != null) { - List list = new LinkedList<>(); - list.add(dataValue); - MData data = selectedNode.getAttr(shortName); - if (data != null) { - data.parse(list); - // System.out.println("PARSE DV "+shortName+" " +dataValue + " => " +data); - } - } - } - - private void doConnectAttr() { - String src = nextArg(); - String dst = nextArg(); - if (src.startsWith(":")) { - src = src.substring(1); - } - MPath srcPath = new MPath(env, src); - MPath dstPath = new MPath(env, dst); - MData srcData = srcPath.apply(); - MData dstData = dstPath.apply(); - env.connectAttr(src, dst); - if (srcData instanceof MPointer) { - ((MPointer) srcData).setTarget(dstPath); - } - if (dstData instanceof MPointer) { - ((MPointer) dstData).setTarget(srcPath); - } - // System.out.println("CONNECT ATTR: " + srcData + " " + dstData); - } - - private void doCreateNode() { - String name = null; - String parent = null; - String type = null; - boolean shared = false; - boolean select = true; - while (moreArgs()) { - String tok = nextArg(); - switch (tok) { - case "-name": - case "-n": - name = nextArg(); - break; - case "-parent": - case "-p": - parent = nextArg(); - break; - case "-shared": - case "-s": - shared = true; - break; - case "-skipSelect": - case "-ss": - select = false; - break; - default: - if (type != null) { - throw error("Node type (" + type - + ") already specified, can't specify new one (" - + tok + ")"); - } - type = tok; - break; - } - - } - if (type == null) { - throw error("Node type not specified"); - } - if ("script".equals(type)) { - inPlaybackScriptNode = true; - return; - } - // Execute the node creation - if (shared && env.findNode(name) != null) { - // Don't create this node again - return; - } - MNode parentNode = null; - if (parent != null) { - parentNode = env.findNode(parent); - } - MNode node = env.createNode(type, name); - if (node != null) { - if (parentNode != null) { - node.setParentNode(parentNode); - } - env.addNode(node); - if (select) { - selectedNode = node; - } - } else { - selectedNode = null; - } - } - - private void doCurrentUnit() { - } - - private void doDisconnectAttr() { - } - - private void doFile() { - String fileName = null; - while (moreArgs()) { - fileName = nextArg(); - } - if (fileName != null && !refs.contains(fileName)) { - refs.add(fileName); - try { - new MParser(env).parse(new URL(inputSource, fileName)); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private void doFileInfo() { - } - - private void doParent() { - String instance = null; - String source = null; - for (int i = 0; i < curArgs.size(); i++) { - String arg = curArgs.get(i); - if (!arg.startsWith("-")) { - source = arg; - } else if (arg.equals("-add")) { - instance = curArgs.get(++i); - } - } - if (source != null && instance != null) { - MPath spath = new MPath(env, source); - MPath ipath = new MPath(env, instance); - MNode inode = ipath.getTargetNode(); - if (inode != null) { - inode.parent(spath.getTargetNode()); - } - } - } - - private void doRequires() { - } - - private void doSelect() { - String path = null; - for (int i = 0; i < curArgs.size(); i++) { - String arg = curArgs.get(i); - if (!arg.startsWith("-")) { - path = arg; - break; - } - } - if (path != null) { - MPath mpath = new MPath(env, path); - // System.out.println("SELECTED: " + mpath); - selectedNode = mpath.getTargetNode(); - } - } - - private void doSetAttr() { - String target = null; - List value = new ArrayList<>(); - @SuppressWarnings("unused") - String type = null; - int size = -1; - for (int i = 0; i < curArgs.size(); i++) { - String arg = curArgs.get(i); - if (arg.equals("-s") || arg.equals("-size")) { - try { - size = Integer.parseInt(curArgs.get(++i)); - } catch (Exception ignored) { - ignored.printStackTrace(System.err); - } - } else if (arg.equals("-type") || arg.equals("-typ")) { - //noinspection UnusedAssignment - type = curArgs.get(++i); - } else if (target == null - && (arg.equals("-l") || arg.equals("-lock"))) { - ++i; - } else if (target == null - && (arg.equals("-k") || arg.equals("-keyable"))) { - ++i; - } else if (target == null - && (arg.equals("-ch") || arg.equals("-capacityHint"))) { - ++i; - } else if (target == null) { - target = arg; - } else { - value.add(arg); - } - } - if (inPlaybackScriptNode) { - // System.out.println("set attr playback script: "+ target); - if (".b".equals(target)) { - inPlaybackScriptNode = false; - try { - String playBackOptions = value.get(0); - // System.out.println("playBackOptions = " + playBackOptions); - // System.out.println("value.size="+value.size()); - // System.out.println("value="+value); - StringTokenizer izer = new StringTokenizer(playBackOptions, - " "); - izer.nextToken(); // playBackOptions; - float min = 0; - float max = 0; - while (izer.hasMoreTokens()) { - String key = izer.nextToken(); - String val = ""; - if (key.startsWith("-")) { - val = izer.nextToken(); - } - // System.out.println("key="+key); - // System.out.println("value="+val); - switch (key) { - case "-min": - min = Float.parseFloat(val.trim()); - break; - case "-max": - max = Float.parseFloat(val.trim()); - break; - case "-ast": - break; - case "-aet": - break; - } - } - // System.out.println("min="+min+" max="+max); - env.setPlaybackRange(min, max); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - return; - } - - if (selectedNode == null) { - return; - } - - MData data = selectedNode.getAttr(target.substring(1)); - if (data == null) { - // System.err.println("NO ATTRIBUTE: " + target.substring(1) + " ON NODE " + selectedNode.getName()); - return; - } - if (size > 0) { - data.setSize(size); - } - if (value.isEmpty()) { - // System.err.println("NO VALUE: " + curArgs); - // no value, just flag - return; - } - // System.err.println("TELLING " + target.substring(1) + " TO PARSE VALUE " + value); - try { - data.parse(value); - } catch (Exception e) { - if (MayaImporter.DEBUG) { - e.printStackTrace(System.err); - } - } - } - - private RuntimeException error(String error) { - return new RuntimeException(error + ", current command " + curCommand - + ", file " + inputSource + ", line " - + lineNo); - } - - private void execute(List commandArgs) { - String command = commandArgs.remove(0); - curCommand = command; - curArgs = commandArgs; - switch (command) { - case "file": - doFile(); - break; - case "requires": - doRequires(); - break; - case "createNode": - doCreateNode(); - break; - case "setAttr": - doSetAttr(); - break; - case "addAttr": - doAddAttr(); - break; - case "parent": - doParent(); - break; - case "connectAttr": - doConnectAttr(); - break; - case "disconnectAttr": - doDisconnectAttr(); - break; - case "select": - doSelect(); - break; - case "currentUnit": - doCurrentUnit(); - break; - case "fileInfo": - doFileInfo(); - break; - default: - System.out.println("Unrecognized command " + command); - break; - } - } - - private boolean moreArgs() { - return curArgs.size() > 0; - } - - private String nextArg() { - if (curArgs.size() > 0) { - return curArgs.remove(0); - } - throw error("No more arguments for command \"" + curCommand + "\""); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MArrayType.java deleted file mode 100644 index a2aeb38..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MArrayType.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MArrayImpl; - -public class MArrayType extends MDataType { - - MDataType elementType; - - public MArrayType(MEnv env, MDataType elementType) { - super(env, elementType.getName() + "[]"); - this.elementType = elementType; - } - - @Override - public MData createData() { - return new MArrayImpl(this); - } - - public MDataType getElementType() { - return elementType; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MAttributeAliasType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MAttributeAliasType.java deleted file mode 100644 index b8a9d36..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MAttributeAliasType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MAttributeAliasImpl; - -public class MAttributeAliasType extends MDataType { - - public static final String NAME = "attributeAlias"; - - public MAttributeAliasType(MEnv env) { - this(env, NAME); - } - - public MAttributeAliasType(MEnv env, String name) { - super(env, name); - } - - @Override - public MData createData() { - return new MAttributeAliasImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MBoolType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MBoolType.java deleted file mode 100644 index 02e590f..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MBoolType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MBoolImpl; - -public class MBoolType extends MDataType { - - public static final String NAME = "bool"; - - public MBoolType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MBoolImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCharacterMappingType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCharacterMappingType.java deleted file mode 100644 index e533e46..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCharacterMappingType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MCharacterMappingImpl; - -public class MCharacterMappingType extends MDataType { - - public static final String NAME = "characterMapping"; - - public MCharacterMappingType(MEnv env) { - this(env, NAME); - } - - public MCharacterMappingType(MEnv env, String name) { - super(env, name); - } - - @Override - public MData createData() { - return new MCharacterMappingImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MComponentListType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MComponentListType.java deleted file mode 100644 index 7a450d5..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MComponentListType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MComponentListImpl; - -public class MComponentListType extends MDataType { - - public static final String NAME = "componentList"; - - public MComponentListType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MComponentListImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCompoundType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCompoundType.java deleted file mode 100644 index 24047a1..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MCompoundType.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MCompoundImpl; - -public class MCompoundType extends MDataType { - - public static class Field { - MData defaultValue; - int index; - String name; - MDataType type; - - public Field(String name, MDataType type, MData defaultValue, - int index) { - this.name = name; - this.type = type; - this.defaultValue = defaultValue; - this.index = index; - } - - public MData getDefault() { - //return defaultValue; - return type.createData(); - } - - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - - public MDataType getType() { - return type; - } - } - - List fieldArray = new ArrayList<>(); - - Map fields = new HashMap<>(); - - public MCompoundType(MEnv env, String name) { - super(env, name); - } - - public Field addField(String name, MDataType type, MData defaultValue) { - Field field; - fields.put(name, field = new Field(name, type, defaultValue, - fieldArray.size())); - fieldArray.add(field); - return field; - } - - @Override - public MData createData() { - return new MCompoundImpl(this); - } - - public Field getField(int index) { - return fieldArray.get(index); - } - - public Field getField(String name) { - return fields.get(name); - } - - public int getFieldIndex(String name) { - Field field = getField(name); - if (field == null) { - // System.out.println("No such field in type " + getName() + ": " + name); - return -1; - } - return getField(name).getIndex(); - } - - public Map getFields() { - return fields; - } - - public int getNumFields() { - return fieldArray.size(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MDataType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MDataType.java deleted file mode 100644 index c509723..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MDataType.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.MObject; -import com.javafx.experiments.importers.maya.values.MData; - -public abstract class MDataType extends MObject { - public MDataType(MEnv env, String name) { - super(env, name); - } - - @Override - public void accept(MEnv.Visitor visitor) { - visitor.visitDataType(this); - } - - public abstract MData createData(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2ArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2ArrayType.java deleted file mode 100644 index 20a85b5..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2ArrayType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloat2ArrayImpl; - -public class MFloat2ArrayType extends MDataType { - - public static final String NAME = "float2[]"; - - public MFloat2ArrayType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MFloat2ArrayImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2Type.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2Type.java deleted file mode 100644 index f4dd25e..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat2Type.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloat2Impl; - -public class MFloat2Type extends MDataType { - - public static final String NAME = "float2"; - - public MFloat2Type(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MFloat2Impl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3ArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3ArrayType.java deleted file mode 100644 index 6582aea..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3ArrayType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloat3ArrayImpl; - -public class MFloat3ArrayType extends MDataType { - - public static final String NAME = "float3[]"; - - public MFloat3ArrayType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MFloat3ArrayImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3Type.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3Type.java deleted file mode 100644 index 7713629..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloat3Type.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloat3Impl; - -public class MFloat3Type extends MDataType { - - public static final String NAME = "float3"; - - public MFloat3Type(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MFloat3Impl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatArrayType.java deleted file mode 100644 index f3dd950..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatArrayType.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloatArrayImpl; - -public class MFloatArrayType extends MDataType { - - public static final String NAME = "float[]"; - - public MFloatArrayType(MEnv env) { - this(env, NAME); - } - - public MFloatArrayType(MEnv env, String name) { - super(env, name); - } - - @Override - public MData createData() { - return new MFloatArrayImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatType.java deleted file mode 100644 index 3f7292f..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MFloatType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MFloatImpl; - -public class MFloatType extends MDataType { - - public static final String NAME = "float"; - - public MFloatType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MFloatImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MInt3ArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MInt3ArrayType.java deleted file mode 100644 index 514f5ab..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MInt3ArrayType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MInt3ArrayImpl; - -public class MInt3ArrayType extends MDataType { - - public static final String NAME = "int3[]"; - - public MInt3ArrayType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MInt3ArrayImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntArrayType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntArrayType.java deleted file mode 100644 index 748742e..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntArrayType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MIntArrayImpl; - -public class MIntArrayType extends MDataType { - - public static final String NAME = "int[]"; - - public MIntArrayType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MIntArrayImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntType.java deleted file mode 100644 index e114e97..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MIntType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MIntImpl; - -public class MIntType extends MDataType { - - public static final String NAME = "int"; - - public MIntType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MIntImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MMatrixType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MMatrixType.java deleted file mode 100644 index 5c42cbd..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MMatrixType.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloatArray; -import com.javafx.experiments.importers.maya.values.impl.MFloatArrayImpl; - -public class MMatrixType extends MFloatArrayType { - - public static final String NAME = "matrix"; - - public MMatrixType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - MFloatArray array = new MFloatArrayImpl(this); - array.setSize(16); - // Make the default value the identity matrix - array.set(0, 1); - array.set(5, 1); - array.set(10, 1); - array.set(15, 1); - return array; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MNurbsCurveType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MNurbsCurveType.java deleted file mode 100644 index f37a831..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MNurbsCurveType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MNurbsCurveImpl; - -public class MNurbsCurveType extends MDataType { - - public static final String NAME = "nurbsCurve"; - - public MNurbsCurveType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MNurbsCurveImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPointerType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPointerType.java deleted file mode 100644 index dd79bee..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPointerType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MPointerImpl; - -public class MPointerType extends MDataType { - - public static final String NAME = "Message"; - - public MPointerType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MPointerImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPolyFaceType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPolyFaceType.java deleted file mode 100644 index f8c4387..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MPolyFaceType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MPolyFaceImpl; - -public class MPolyFaceType extends MDataType { - - public static final String NAME = "polyFace"; - - public MPolyFaceType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MPolyFaceImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MStringType.java b/gui/src/main/java/com/javafx/experiments/importers/maya/types/MStringType.java deleted file mode 100644 index 4cbf333..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/types/MStringType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.types; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.impl.MStringImpl; - -public class MStringType extends MDataType { - - public static final String NAME = "string"; - - public MStringType(MEnv env) { - super(env, NAME); - } - - @Override - public MData createData() { - return new MStringImpl(this); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MArray.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MArray.java deleted file mode 100644 index eb98e74..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MArray.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import java.util.List; - -public interface MArray extends MData { - /** Get all of the data in this array. */ - public List get(); - - public int getSize(); - - /** Set one element of this array. */ - public void set(int index, MData data); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MAttributeAlias.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MAttributeAlias.java deleted file mode 100644 index 6dee4ea..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MAttributeAlias.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import java.util.Map; - -public interface MAttributeAlias extends MData { - public Map getMapping(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MBool.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MBool.java deleted file mode 100644 index 38521fc..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MBool.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MBool extends MData { - public boolean get(); - - public void set(boolean value); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCharacterMapping.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCharacterMapping.java deleted file mode 100644 index be8c6cb..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCharacterMapping.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MCharacterMapping extends MData { - public interface Entry { - public String getKey(); - - public int getSourceIndex(); - - public int getTargetIndex(); - } - - public Entry[] getMapping(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MComponentList.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MComponentList.java deleted file mode 100644 index cda05c2..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MComponentList.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import java.util.List; - -public interface MComponentList extends MData { - public static class Component { - public static Component parse(String str) { - String name = null; - int startIndex = 0; - int endIndex = 0; - - int bracket = str.indexOf("["); - int endBracket = str.indexOf("]"); - if (bracket < 0) { - name = str; - startIndex = -1; - } else { - name = str.substring(0, bracket); - if (str.charAt(bracket + 1) == '*') { - startIndex = -1; - endIndex = -1; - } else { - int i = bracket + 1; - for (; i < endBracket; i++) { - if (str.charAt(i) == ':') { - break; - } - startIndex *= 10; - startIndex += str.charAt(i) - '0'; - } - if (str.charAt(i) == ':') { - i++; - for (; i < endBracket; i++) { - endIndex *= 10; - endIndex += str.charAt(i) - '0'; - } - } else { - endIndex = startIndex; - } - } - } - - return new Component(name, startIndex, endIndex); - } - - private int endIndex; // Inclusive - // Ideally we would have an enum of these, but we don't know all of the mappings yet. - // The possible values are listed in MFn::Type (MFn.h), but not the names. - // Here are some, derived by using the Maya selection tool and - // watching the script editor output: - // "f[i]" -> faces - // "vtx[i]" -> vertices - // "e[i]" -> edges - // "map[i]" -> uvs - // "vtxFace[i][j]" -> vertices within faces - private String name; - - private int startIndex; // Or -1 if "all" - - public Component(String name, int startIndex, int endIndex) { - this.name = name; - this.startIndex = startIndex; - this.endIndex = endIndex; - } - - public int endIndex() { - return endIndex; - } - - public String name() { - return name; - } - - public int startIndex() { - return startIndex; - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append(name); - buf.append("["); - if (startIndex < 0) { - buf.append("*"); - } else { - buf.append(startIndex); - if (endIndex > startIndex) { - buf.append(":"); - buf.append(endIndex); - } - } - buf.append("]"); - return buf.toString(); - } - } - - public List get(); - - public void set(List value); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCompound.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCompound.java deleted file mode 100644 index d874fdb..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MCompound.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import com.javafx.experiments.importers.maya.types.MCompoundType; - -public interface MCompound extends MData { - public MCompoundType getCompoundType(); - - public MData getFieldData(int fieldIndex); - - @Override - public MData getFieldData(String fieldName); - - public void set(int fieldIndex, MData value); - - public void set(String fieldName, MData data); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MData.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MData.java deleted file mode 100644 index 07d2b00..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MData.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import java.util.Iterator; -import java.util.List; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.types.MDataType; - -public interface MData { - /** Index access for those values which suport it, such as array values. */ - public MData getData(int index); - - /** Slice access for those values which support it, such as array values. */ - public MData getData(int start, int end); - - /** Get the data associated with the given string path. */ - public MData getData(String path); - - public MEnv getEnv(); - - /** - * Field access for those values which support it, such as compound values. - */ - public MData getFieldData(String name); - - public MDataType getType(); - - public void parse(Iterator iter); - - public void parse(List values); - - public void parse(String field, List values); - - public void setSize(int size); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat.java deleted file mode 100644 index d418089..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloat extends MData { - public float get(); - - public void set(float value); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2.java deleted file mode 100644 index 9e17098..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloat2 extends MData { - public float[] get(); - - public float get(int index); - - public float getX(); - - public float getY(); - - public void set(float x, float y); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2Array.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2Array.java deleted file mode 100644 index 572a906..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat2Array.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloat2Array extends MData { - public float[] get(); - - public int getSize(); - - public void set(int index, float x, float y); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3.java deleted file mode 100644 index 85411e3..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloat3 extends MData { - public float[] get(); - - public float get(int i); - - public float getX(); - - public float getY(); - - public float getZ(); - - public void set(float x, float y, float z); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3Array.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3Array.java deleted file mode 100644 index b453ff9..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloat3Array.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloat3Array extends MData { - public float[] get(); - - public int getSize(); - - public void set(int index, float x, float y, float z); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloatArray.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloatArray.java deleted file mode 100644 index 532d70f..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MFloatArray.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MFloatArray extends MData { - public float[] get(); - - public float get(int index); - - public int getSize(); - - public void set(int index, float x); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt.java deleted file mode 100644 index 90091dc..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MInt extends MData { - public int get(); - - public void set(int value); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt3Array.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt3Array.java deleted file mode 100644 index db14685..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MInt3Array.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MInt3Array extends MData { - public int[] get(); - - public int getSize(); - - public void set(int index, int x, int y, int z); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MIntArray.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MIntArray.java deleted file mode 100644 index 6f3e728..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MIntArray.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MIntArray extends MData { - public int[] get(); - - public int get(int index); - - public int getSize(); - - public void set(int index, int x); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MNurbsCurve.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MNurbsCurve.java deleted file mode 100644 index 57d2785..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MNurbsCurve.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MNurbsCurve extends MData { - public float[] getCVs(); - - public int getDegree(); - - public int getDimension(); - - public int getForm(); - - public float[] getKnots(); - - public int getNumCVs(); - - public int getNumKnots(); - - public int getSpans(); - - public boolean isRational(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPointer.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPointer.java deleted file mode 100644 index 3971ce2..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPointer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import com.javafx.experiments.importers.maya.MNode; -import com.javafx.experiments.importers.maya.MPath; - -public interface MPointer extends MData { - public MPath getTarget(); - - public MNode getTargetNode(); - - public void setTarget(MPath path); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPolyFace.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPolyFace.java deleted file mode 100644 index bdb52c3..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MPolyFace.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -import java.util.List; - -public interface MPolyFace extends MData { - public static class FaceData { - private int[] faceColors; - private int[] faceEdges; - private int[] holeEdges; - private int[][] uvData; - - public int[] getFaceColors() { - return faceColors; - } - - public int[] getFaceEdges() { - return faceEdges; - } - - public int[] getHoleEdges() { - return holeEdges; - } - - public int[][] getUVData() { - return uvData; - } - - public void setFaceColors(int[] faceColors) { - this.faceColors = faceColors; - } - - public void setFaceEdges(int[] faceEdges) { - this.faceEdges = faceEdges; - } - - public void setHoleEdges(int[] holeEdges) { - this.holeEdges = holeEdges; - } - - public void setUVData(int index, int[] data) { - if (uvData == null || index >= uvData.length) { - int[][] newUVData = new int[index + 1][]; - if (uvData != null) { - System.arraycopy(uvData, 0, newUVData, 0, uvData.length); - } - uvData = newUVData; - } - uvData[index] = data; - } - - @Override - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append("[FaceData faceEdges: "); - appendIntArray(buf, faceEdges); - buf.append(" holeEdges: "); - appendIntArray(buf, holeEdges); - buf.append(" uvData: "); - append2DIntArray(buf, uvData); - buf.append(" faceColors: "); - appendIntArray(buf, faceColors); - buf.append("]"); - return buf.toString(); - } - - private void append2DIntArray(StringBuffer buf, int[][] array) { - if (array == null) { - buf.append(array); - } else { - buf.append("["); - for (int[] element : array) { - appendIntArray(buf, element); - } - buf.append("]"); - } - } - - private void appendIntArray(StringBuffer buf, int[] array) { - if (array == null) { - buf.append(array); - } else { - buf.append("["); - for (int element : array) { - buf.append(" "); - buf.append(element); - } - } - } - } - - public void addFace(FaceData face); - - public List getFaces(); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MString.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/MString.java deleted file mode 100644 index 6c82f49..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/MString.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values; - -public interface MString extends MData { - public String get(); - - public void set(String str); -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MArrayImpl.java deleted file mode 100644 index 42a5352..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MArrayImpl.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.javafx.experiments.importers.maya.MayaImporter; -import com.javafx.experiments.importers.maya.types.MArrayType; -import com.javafx.experiments.importers.maya.values.MArray; -import com.javafx.experiments.importers.maya.values.MData; - -public class MArrayImpl extends MDataImpl implements MArray { - class MArraySlice extends MDataImpl implements MArray { - private MArray array; - private int base; - private int length; - - MArraySlice(MArray array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public List get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public MData getData(int index) { - return array.getData(base + index); - } - - @Override - public MData getData(int start, int end) { - return new MArraySlice(this, start, end - start); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator values) { - new Parser(this).parse(values); - } - - @Override - public void set(int index, MData data) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, data); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MArray array; - - Parser(MArray array) { - this.array = array; - } - - public void parse(Iterator values) { - int i = 0; - while (values.hasNext()) { - array.setSize(i + 1); - // System.out.println("get " + i +" of " + array.getSize()); - array.getData(i) - .parse(values); - i++; - } - } - } - - public static final boolean DEBUG = MayaImporter.DEBUG; - - public static final boolean WARN = MayaImporter.WARN; - - List data = new ArrayList<>(); - - public MArrayImpl(MArrayType type) { - super(type); - } - - @Override - public List get() { - return data; - } - - public MArrayType getArrayType() { - return (MArrayType) getType(); - } - - @Override - public MData getData(int index) { - if (index >= data.size()) { // TODO huge hack, to prevent out of bounds exception - int oldIndex = index; - index = data.size() - 1; - if (WARN) { - System.err.println("Changed index from [" + oldIndex + "] to [" - + index + "]"); - } - } - return data.get(index); - } - - @Override - public MData getData(int start, int end) { - return new MArraySlice(this, start, end - start); - } - - @Override - public int getSize() { - return data.size(); - } - - @Override - public void parse(Iterator values) { - new Parser(this).parse(values); - } - - @Override - public void set(int index, MData data) { - this.data.set(index, data); - } - - @Override - public void setSize(int size) { - while (data.size() < size) { - data.add(getArrayType().getElementType() - .createData()); - } - // System.out.println("SET SIZE: " + size + " data.size="+data.size()); - } - - @Override - public String toString() { - return data.toString(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MAttributeAliasImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MAttributeAliasImpl.java deleted file mode 100644 index 4cf6824..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MAttributeAliasImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.TreeMap; - -import com.javafx.experiments.importers.maya.types.MAttributeAliasType; -import com.javafx.experiments.importers.maya.values.MAttributeAlias; - -public class MAttributeAliasImpl extends MDataImpl implements MAttributeAlias { - - Map map = new TreeMap(); - - public MAttributeAliasImpl(MAttributeAliasType type) { - super(type); - } - - @Override - public Map getMapping() { - return map; - } - - @Override - public void parse(Iterator values) { - List list = new ArrayList(); - while (values.hasNext()) { - String str = values.next(); - int start = str.indexOf("\""); - if (start < 0) { - System.out.println("parse error at: " + str); - continue; - } - str = str.substring(start); - StringTokenizer izer = new StringTokenizer(str, ","); - while (izer.hasMoreTokens()) { - String tok = izer.nextToken(); - tok = tok.substring(1, tok.length() - 1); - list.add(tok); - } - } - for (int i = 0; i < list.size(); i += 2) { - map.put(list.get(i), list.get(i + 1)); - } - System.out.println("parsed aal: " + map); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MBoolImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MBoolImpl.java deleted file mode 100644 index 8dcfee7..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MBoolImpl.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MBoolType; -import com.javafx.experiments.importers.maya.values.MBool; - -public class MBoolImpl extends MDataImpl implements MBool { - - private boolean value; - - public MBoolImpl(MBoolType type) { - super(type); - } - - @Override - public boolean get() { - return value; - } - - @Override - public void parse(Iterator values) { - String val = values.next(); - if (val.equals("yes") || val.equals("true")) { - value = true; - } else { - value = false; - } - } - - @Override - public void set(boolean value) { - this.value = value; - } - - @Override - public String toString() { - String result = getType().getName(); - result += " " + value; - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCharacterMappingImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCharacterMappingImpl.java deleted file mode 100644 index e6438c5..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCharacterMappingImpl.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MCharacterMappingType; -import com.javafx.experiments.importers.maya.values.MCharacterMapping; - -public class MCharacterMappingImpl extends MDataImpl - implements MCharacterMapping { - - class EntryImpl implements Entry { - String key; - - int sourceIndex; - - int targetIndex; - - public EntryImpl(String key, int sourceIndex, int targetIndex) { - this.key = key; - this.sourceIndex = sourceIndex; - this.targetIndex = targetIndex; - } - - @Override - public String getKey() { - return key; - } - - @Override - public int getSourceIndex() { - return sourceIndex; - } - - @Override - public int getTargetIndex() { - return targetIndex; - } - } - - Entry[] entries; - - public MCharacterMappingImpl(MCharacterMappingType type) { - super(type); - } - - @Override - public Entry[] getMapping() { - return entries; - } - - @Override - public void parse(Iterator values) { - int count = Integer.parseInt(values.next()); - entries = new Entry[count]; - for (int i = 0; i < count; i++) { - String k = values.next(); - int i1 = Integer.parseInt(values.next()); - int i2 = Integer.parseInt(values.next()); - entries[i] = new EntryImpl(k, i1, i2); - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MComponentListImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MComponentListImpl.java deleted file mode 100644 index d1422a9..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MComponentListImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.javafx.experiments.importers.maya.types.MComponentListType; -import com.javafx.experiments.importers.maya.values.MComponentList; - -public class MComponentListImpl extends MDataImpl implements MComponentList { - - private List components = new ArrayList(); - - public MComponentListImpl(MComponentListType type) { - super(type); - } - - @Override - public List get() { - return components; - } - - @Override - public void parse(Iterator values) { - try { - int num = Integer.parseInt(values.next()); - for (int i = 0; i < num; i++) { - components.add(Component.parse(values.next())); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void set(List value) { - components = value; - } - - @Override - public String toString() { - StringBuffer res = new StringBuffer(); - res.append(getType().getName()); - for (Component c : components) { - res.append(" "); - res.append(c); - } - return res.toString(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCompoundImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCompoundImpl.java deleted file mode 100644 index 3741a76..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MCompoundImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MCompoundType; -import com.javafx.experiments.importers.maya.types.MDataType; -import com.javafx.experiments.importers.maya.values.MCompound; -import com.javafx.experiments.importers.maya.values.MData; - -public class MCompoundImpl extends MDataImpl implements MCompound { - private MData[] fieldData; - - public MCompoundImpl(MCompoundType type) { - super(type); - fieldData = new MData[type.getNumFields()]; - for (int i = 0; i < fieldData.length; i++) { - MDataType dt = getCompoundType().getField(i) - .getType(); - if (dt != null) { - fieldData[i] = dt.createData(); - } else { - // System.out.println("field data type is null: " + getCompoundType().getField(i).getName()); - } - } - } - - @Override - public MCompoundType getCompoundType() { - return (MCompoundType) getType(); - } - - @Override - public MData getFieldData(int fieldIndex) { - if (fieldIndex < 0) { - return null; - } - return fieldData[fieldIndex]; - } - - @Override - public MData getFieldData(String fieldName) { - return getFieldData(getCompoundType().getFieldIndex(fieldName)); - } - - @Override - public void parse(Iterator data) { - for (int i = 0; i < getCompoundType().getNumFields(); i++) { - MData fdata = getFieldData(i); - if (fdata != null) { - fdata.parse(data); - } - } - } - - @Override - public void set(int fieldIndex, MData value) { - fieldData[fieldIndex] = value; - } - - @Override - public void set(String fieldName, MData data) { - set(getCompoundType().getFieldIndex(fieldName), data); - } - - @Override - public String toString() { - String result = ""; - for (int i = 0; i < fieldData.length; i++) { - result += getCompoundType().getField(i) - .getName() - + ":\t" + fieldData[i] + "\n"; - } - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MDataImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MDataImpl.java deleted file mode 100644 index f701f6e..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MDataImpl.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; -import java.util.List; - -import com.javafx.experiments.importers.maya.MEnv; -import com.javafx.experiments.importers.maya.types.MDataType; -import com.javafx.experiments.importers.maya.values.MData; - -public abstract class MDataImpl implements MData { - - private MDataType dataType; - - public MDataImpl(MDataType type) { - dataType = type; - } - - // Index access for those values which suport it, such as array values - @Override - public MData getData(int index) { - if (index == 0) { - return this; - } - return null; - } - - // Slice access for those values which support it, such as array values - @Override - public MData getData(int start, int end) { - if (start == 0 && end == 0) { - return this; - } - return null; - } - - // Get the data associated with the given string path - @Override - public MData getData(String path) { - // System.out.println("get: "+ path); - return doGet(path, 0); - } - - @Override - public MEnv getEnv() { - return getType().getEnv(); - } - - // Field access for those values which support it, such as compound values - @Override - public MData getFieldData(String name) { - if (name.length() == 0) { - return this; - } - return null; - } - - @Override - public MDataType getType() { - return dataType; - } - - @Override - public abstract void parse(Iterator iter); - - @Override - public void parse(List values) { - parse(values.iterator()); - } - - @Override - public void parse(String field, List values) { - MData value = doGet(field, 0); - if (value == null) { - // System.out.println("field value is null: " +field + " in " + getType().getName()); - } - value.parse(values); - } - - @Override - public void setSize(int size) { - // nothing - } - - // Dereference from this MData down the path, starting parsing at the current point - protected MData doGet(String path, int start) { - if (start == path.length()) { - return this; - } - int dot = path.indexOf('.', start); - int bracket = path.indexOf('[', start); - if (dot == start) { - return doGet(path, start + 1); - } else if (bracket == start) { - int endBracket = path.indexOf(']', start); - int sliceStart = 0; - int sliceEnd = 0; - int i = start + 1; - for (; i < endBracket; i++) { - if (path.charAt(i) == ':') { - break; - } - sliceStart *= 10; - sliceStart += path.charAt(i) - '0'; - } - if (path.charAt(i) == ':') { - i++; - for (; i < endBracket; i++) { - sliceEnd *= 10; - sliceEnd += path.charAt(i) - '0'; - } - // FIXME: downcast undesirable - return ((MDataImpl) getData(sliceStart, - sliceEnd)).doGet(path, - endBracket + 1); - } else { - // FIXME: downcast undesirable - return ((MDataImpl) getData(sliceStart)).doGet(path, - endBracket + 1); - } - } else { - int endIdx; - if (dot < 0 && bracket < 0) { - endIdx = path.length(); - } else { - if (dot < 0) { - endIdx = bracket; - } else if (bracket < 0) { - endIdx = dot; - } else { - endIdx = Math.min(dot, bracket); - } - } - String field = path.substring(start, endIdx); - MData data = getFieldData(field); - if (data == null) { - // System.err.println("WARNING: field data not found: "+field + " in "+ getType().getName()); - return null; - } else { - // FIXME: downcast undesirable - return ((MDataImpl) data).doGet(path, endIdx); - } - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2ArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2ArrayImpl.java deleted file mode 100644 index 30f47f1..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2ArrayImpl.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloat2ArrayType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat2Array; - -public class MFloat2ArrayImpl extends MDataImpl implements MFloat2Array { - - static class MFloat2ArraySlice extends MDataImpl implements MFloat2Array { - private MFloat2Array array; - private int base; - private int length; - - MFloat2ArraySlice(MFloat2Array array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public float[] get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x, float y) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, x, y); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MFloat2Array array; - - Parser(MFloat2Array array) { - this.array = array; - } - - public void parse(Iterator elements) { - int i = 0; - while (elements.hasNext()) { - array.set(i++, Float.parseFloat(elements.next()), - Float.parseFloat(elements.next())); - } - } - } - - private float[] data; - - public MFloat2ArrayImpl(MFloat2ArrayType type) { - super(type); - } - - @Override - public float[] get() { - return data; - } - - @Override - public MData getData(int index) { - // FIXME: should this return an MFloat2 rather than an MFloat2Array? - return getData(index, index + 1); - } - - @Override - public MData getData(int start, int end) { - return new MFloat2ArraySlice(this, start, end - start + 1); - } - - @Override - public int getSize() { - return data == null ? 0 : data.length / 2; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x, float y) { - data[2 * index + 0] = x; - data[2 * index + 1] = y; - } - - @Override - public void setSize(int size) { - if (data == null || 2 * size > data.length) { - float[] newdata = new float[2 * size]; - if (data != null) { - System.arraycopy(data, 0, newdata, 0, data.length); - } - data = newdata; - } - } - - @Override - public String toString() { - String result = getType().getName(); - String sep = " "; - if (data != null) { - for (float f : data) { - result += sep; - result += f; - } - } - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2Impl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2Impl.java deleted file mode 100644 index a99eb07..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat2Impl.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloat2Type; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat; -import com.javafx.experiments.importers.maya.values.MFloat2; - -public class MFloat2Impl extends MDataImpl implements MFloat2 { - - class MFloat2Component extends MDataImpl implements MFloat { - private int index; - - MFloat2Component(int index) { - super(MFloat2Impl.this.getEnv() - .findDataType("float")); - this.index = index; - } - - @Override - public float get() { - return data[index]; - } - - @Override - public void parse(Iterator elements) { - data[index] = Float.parseFloat(elements.next()); - } - - @Override - public void set(float value) { - data[index] = value; - } - } - - private float[] data = new float[2]; - - public MFloat2Impl(MFloat2Type type) { - super(type); - } - - @Override - public float[] get() { - return data; - } - - @Override - public float get(int index) { - return data[index]; - } - - @Override - public MData getData(int index) { - return new MFloat2Component(index); - } - - @Override - public MData getData(String name) { - if (name.equals("x")) { - return getData(0); - } else if (name.equals("y")) { - return getData(1); - } - return super.getData(name); - } - - @Override - public float getX() { - return data[0]; - } - - @Override - public float getY() { - return data[1]; - } - - @Override - public void parse(Iterator elements) { - for (int i = 0; i < 2; i++) { - data[i] = Float.parseFloat(elements.next()); - } - } - - @Override - public void set(float x, float y) { - data[0] = x; - data[1] = y; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3ArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3ArrayImpl.java deleted file mode 100644 index 818ddad..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3ArrayImpl.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloat3ArrayType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat3Array; - -public class MFloat3ArrayImpl extends MDataImpl implements MFloat3Array { - - static class MFloat3ArraySlice extends MDataImpl implements MFloat3Array { - private MFloat3Array array; - private int base; - private int length; - - MFloat3ArraySlice(MFloat3Array array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public float[] get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x, float y, float z) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, x, y, z); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MFloat3Array array; - - Parser(MFloat3Array array) { - this.array = array; - } - - public void parse(Iterator elements) { - int i = 0; - while (elements.hasNext()) { - array.set(i++, Float.parseFloat(elements.next()), - Float.parseFloat(elements.next()), - Float.parseFloat(elements.next())); - } - } - } - - private float[] data; - - public MFloat3ArrayImpl(MFloat3ArrayType type) { - super(type); - } - - @Override - public float[] get() { - return data; - } - - @Override - public MData getData(int index) { - // FIXME: should this return an MFloat3 rather than an MFloat3Array? - return getData(index, index + 1); - } - - @Override - public MData getData(int start, int end) { - return new MFloat3ArraySlice(this, start, end - start + 1); - } - - @Override - public int getSize() { - return data == null ? 0 : data.length / 3; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x, float y, float z) { - data[3 * index + 0] = x; - data[3 * index + 1] = y; - data[3 * index + 2] = z; - } - - @Override - public void setSize(int size) { - if (data == null || 3 * size > data.length) { - float[] newdata = new float[3 * size]; - if (data != null) { - System.arraycopy(data, 0, newdata, 0, data.length); - } - data = newdata; - } - } - - @Override - public String toString() { - String result = getType().getName(); - String sep = " "; - if (data != null) { - for (float f : data) { - result += sep; - result += f; - } - } - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3Impl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3Impl.java deleted file mode 100644 index 341cb04..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloat3Impl.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloat3Type; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloat; -import com.javafx.experiments.importers.maya.values.MFloat3; - -public class MFloat3Impl extends MDataImpl implements MFloat3 { - - class MFloat3Component extends MDataImpl implements MFloat { - private int index; - - MFloat3Component(int index) { - super(MFloat3Impl.this.getEnv() - .findDataType("float")); - this.index = index; - } - - @Override - public float get() { - return data[index]; - } - - @Override - public void parse(Iterator elements) { - data[index] = Float.parseFloat(elements.next()); - } - - @Override - public void set(float value) { - data[index] = value; - } - } - - private float[] data = new float[3]; - - public MFloat3Impl(MFloat3Type type) { - super(type); - } - - @Override - public float[] get() { - return data; - } - - @Override - public float get(int index) { - return data[index]; - } - - @Override - public MData getData(int index) { - return new MFloat3Component(index); - } - - @Override - public MData getData(String name) { - if (name.equals("x")) { - return getData(0); - } else if (name.equals("y")) { - return getData(1); - } else if (name.equals("z")) { - return getData(2); - } - return super.getData(name); - } - - @Override - public float getX() { - return data[0]; - } - - @Override - public float getY() { - return data[1]; - } - - @Override - public float getZ() { - return data[2]; - } - - @Override - public void parse(Iterator elements) { - for (int i = 0; i < 3; i++) { - data[i] = Float.parseFloat(elements.next()); - } - } - - @Override - public void set(float x, float y, float z) { - data[0] = x; - data[1] = y; - data[2] = z; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatArrayImpl.java deleted file mode 100644 index d29c74f..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatArrayImpl.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloatArrayType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MFloatArray; - -public class MFloatArrayImpl extends MDataImpl implements MFloatArray { - - static class MFloatArraySlice extends MDataImpl implements MFloatArray { - private MFloatArray array; - private int base; - private int length; - - MFloatArraySlice(MFloatArray array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public float[] get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public float get(int index) { - return array.get(base + index); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, x); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MFloatArray array; - - Parser(MFloatArray array) { - this.array = array; - } - - public void parse(Iterator elements) { - int i = 0; - // System.out.println("PARSING FLOAT ARRAY"); - while (elements.hasNext()) { - String str = elements.next(); - if ("nan".equals(str)) { - str = "0"; - } - array.set(i++, Float.parseFloat(str)); - } - } - } - - private float[] data; - - public MFloatArrayImpl(MFloatArrayType type) { - super(type); - } - - @Override - public float[] get() { - return data; - } - - @Override - public float get(int index) { - return data[index]; - } - - @Override - public MData getData(int index) { - return getData(index, index + 1); - } - - @Override - public MData getData(int start, int end) { - return new MFloatArraySlice(this, start, end - start + 1); - } - - @Override - public int getSize() { - return data == null ? 0 : data.length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, float x) { - setSize(index + 1); - data[index] = x; - } - - @Override - public void setSize(int size) { - if (data == null || size > data.length) { - float[] newdata = new float[size]; - if (data != null) { - System.arraycopy(data, 0, newdata, 0, data.length); - } - data = newdata; - } - } - - @Override - public String toString() { - String result = getType().getName(); - String sep = " "; - if (data != null) { - for (float f : data) { - result += sep; - result += f; - } - } - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatImpl.java deleted file mode 100644 index 30d417b..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MFloatImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MFloatType; -import com.javafx.experiments.importers.maya.values.MFloat; - -public class MFloatImpl extends MDataImpl implements MFloat { - - float value; - - public MFloatImpl(MFloatType type) { - super(type); - } - - @Override - public float get() { - return value; - } - - @Override - public void parse(Iterator values) { - String val = values.next() - .toLowerCase(); - value = Float.parseFloat(val); - } - - @Override - public void set(float value) { - this.value = value; - } - - @Override - public String toString() { - String result = getType().getName(); - result += " " + value; - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MInt3ArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MInt3ArrayImpl.java deleted file mode 100644 index d23ab79..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MInt3ArrayImpl.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MInt3ArrayType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MInt3Array; - -public class MInt3ArrayImpl extends MDataImpl implements MInt3Array { - - static class MInt3ArraySlice extends MDataImpl implements MInt3Array { - private MInt3Array array; - private int base; - private int length; - - MInt3ArraySlice(MInt3Array array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public int[] get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, int x, int y, int z) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, x, y, z); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MInt3Array array; - - Parser(MInt3Array array) { - this.array = array; - } - - public void parse(Iterator elements) { - int i = 0; - while (elements.hasNext()) { - array.set(i++, Integer.parseInt(elements.next()), - Integer.parseInt(elements.next()), - Integer.parseInt(elements.next())); - } - } - } - - private int[] data; - - public MInt3ArrayImpl(MInt3ArrayType type) { - super(type); - } - - @Override - public int[] get() { - return data; - } - - @Override - public MData getData(int index) { - // FIXME: should we introduce MInt3 and have this return one instead of an MInt3Array? - return getData(index, index + 1); - } - - @Override - public MData getData(int start, int end) { - return new MInt3ArraySlice(this, start, end - start + 1); - } - - @Override - public int getSize() { - return data == null ? 0 : data.length / 3; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, int x, int y, int z) { - data[3 * index + 0] = x; - data[3 * index + 1] = y; - data[3 * index + 2] = z; - } - - @Override - public void setSize(int size) { - if (data == null || 3 * size > data.length) { - int[] newdata = new int[3 * size]; - if (data != null) { - System.arraycopy(data, 0, newdata, 0, data.length); - } - data = newdata; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntArrayImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntArrayImpl.java deleted file mode 100644 index 97dc8a5..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntArrayImpl.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MIntArrayType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MIntArray; - -public class MIntArrayImpl extends MDataImpl implements MIntArray { - - static class MIntArraySlice extends MDataImpl implements MIntArray { - private MIntArray array; - private int base; - private int length; - - MIntArraySlice(MIntArray array, int base, int length) { - super(array.getType()); - this.array = array; - this.base = base; - this.length = length; - } - - @Override - public int[] get() { - // FIXME - throw new RuntimeException("Probably shouldn't fetch the data behind a slice"); - } - - @Override - public int get(int index) { - return array.get(base + index); - } - - @Override - public int getSize() { - return length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, int x) { - if (index >= length) { - throw new ArrayIndexOutOfBoundsException(index); - } - array.set(base + index, x); - } - - @Override - public void setSize(int size) { - array.setSize(base + size); - } - } - - static class Parser { - private MIntArray array; - - Parser(MIntArray array) { - this.array = array; - } - - public void parse(Iterator elements) { - int i = 0; - while (elements.hasNext()) { - array.set(i++, Integer.parseInt(elements.next())); - } - } - } - - private int[] data; - - public MIntArrayImpl(MIntArrayType type) { - super(type); - } - - @Override - public int[] get() { - return data; - } - - @Override - public int get(int index) { - return data[index]; - } - - @Override - public MData getData(int index) { - return getData(index, index + 1); - } - - @Override - public MData getData(int start, int end) { - return new MIntArraySlice(this, start, end - start + 1); - } - - @Override - public int getSize() { - return data == null ? 0 : data.length; - } - - @Override - public void parse(Iterator elements) { - new Parser(this).parse(elements); - } - - @Override - public void set(int index, int x) { - setSize(index + 1); - data[index] = x; - } - - @Override - public void setSize(int size) { - if (data == null || size > data.length) { - int[] newdata = new int[size]; - if (data != null) { - System.arraycopy(data, 0, newdata, 0, data.length); - } - data = newdata; - } - } - - @Override - public String toString() { - String result = getType().getName(); - String sep = " "; - if (data != null) { - for (int f : data) { - result += sep; - result += f; - } - } - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntImpl.java deleted file mode 100644 index 9caf895..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MIntImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MIntType; -import com.javafx.experiments.importers.maya.values.MInt; - -public class MIntImpl extends MDataImpl implements MInt { - - private int value; - - public MIntImpl(MIntType type) { - super(type); - } - - @Override - public int get() { - return value; - } - - @Override - public void parse(Iterator values) { - String val = values.next() - .toLowerCase(); - value = Integer.parseInt(val); - } - - @Override - public void set(int value) { - this.value = value; - } - - @Override - public String toString() { - String result = getType().getName(); - result += " " + value; - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MNurbsCurveImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MNurbsCurveImpl.java deleted file mode 100644 index fc8195e..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MNurbsCurveImpl.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MNurbsCurveType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MNurbsCurve; - -public class MNurbsCurveImpl extends MDataImpl implements MNurbsCurve { - float[] cvs; - int degree; - int dimension; - int form; - float[] knots; - int numCvs; - int numKnots; - boolean rational; - int spans; - - public MNurbsCurveImpl(MNurbsCurveType type) { - super(type); - } - - @Override - public float[] getCVs() { - return cvs; - } - - @Override - public MData getData(int start, int end) { - return this; // hack? - } - - @Override - public int getDegree() { - return degree; - } - - @Override - public int getDimension() { - return dimension; - } - - @Override - public int getForm() { - return form; - } - - @Override - public float[] getKnots() { - return knots; - } - - @Override - public int getNumCVs() { - return numCvs; - } - - @Override - public int getNumKnots() { - return numKnots; - } - - @Override - public int getSpans() { - return spans; - } - - @Override - public boolean isRational() { - return rational; - } - - @Override - public void parse(Iterator values) { - degree = Integer.parseInt(values.next()); - // System.out.println("degree="+degree); - spans = Integer.parseInt(values.next()); - // System.out.println("spans="+spans); - form = Integer.parseInt(values.next()); - values.next(); - // rational = tok.equals("yes"); - // System.out.println("rational="+rational); - dimension = Integer.parseInt(values.next()); - // System.out.println("dimension="+dimension); - numKnots = Integer.parseInt(values.next()); - // System.out.println("numKnots="+numKnots); - knots = new float[numKnots]; - for (int i = 0; i < numKnots; i++) { - knots[i] = Float.parseFloat(values.next()); - // System.out.println("knot="+knots[i]); - } - numCvs = Integer.parseInt(values.next()); - cvs = new float[numCvs * dimension]; - for (int i = 0; i < cvs.length; i++) { - cvs[i] = Float.parseFloat(values.next()); - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPointerImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPointerImpl.java deleted file mode 100644 index b065a7f..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPointerImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.MNode; -import com.javafx.experiments.importers.maya.MPath; -import com.javafx.experiments.importers.maya.types.MPointerType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MPointer; - -public class MPointerImpl extends MDataImpl implements MPointer { - - private MPath target; - - public MPointerImpl(MPointerType type) { - super(type); - } - - public MData get() { - return target.apply(); - } - - @Override - public MPath getTarget() { - return target; - } - - @Override - public MNode getTargetNode() { - return target.getTargetNode(); - } - - @Override - public void parse(Iterator iter) { - // Nothing - } - - public void set(MData data) { - //targetNode.setAttr(targetAttribute, data); - } - - @Override - public void setTarget(MPath path) { - target = path; - } - - @Override - public String toString() { - if (target != null) { - return target.toString(); - } else { - return "Null Pointer"; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPolyFaceImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPolyFaceImpl.java deleted file mode 100644 index 621bb36..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MPolyFaceImpl.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.javafx.experiments.importers.maya.types.MPolyFaceType; -import com.javafx.experiments.importers.maya.values.MData; -import com.javafx.experiments.importers.maya.values.MPolyFace; - -public class MPolyFaceImpl extends MDataImpl implements MPolyFace { - class Parser { - private Iterator curArgs; - - Parser(Iterator args) { - curArgs = args; - } - - public void parse() { - MPolyFace.FaceData curFace = null; - while (moreArgs()) { - String tok = nextArg(); - if (tok.equals("f")) { - if (curFace != null) { - addFace(curFace); - } - curFace = new MPolyFace.FaceData(); - curFace.setFaceEdges(nextIntArray()); - } else if (tok.equals("h")) { - curFace.setHoleEdges(nextIntArray()); - } else if (tok.equals("mu")) { - int uvSet = nextInt(); - curFace.setUVData(uvSet, nextIntArray()); - } else if (tok.equals("fc")) { - curFace.setFaceColors(nextIntArray()); - } - } - if (curFace != null) { - addFace(curFace); - } - } - - private boolean moreArgs() { - return curArgs.hasNext(); - } - - private String nextArg() { - return curArgs.next(); - } - - private int nextInt() { - return Integer.parseInt(nextArg()); - } - - private int[] nextIntArray() { - int num = nextInt(); - int[] res = new int[num]; - for (int i = 0; i < num; i++) { - res[i] = nextInt(); - } - return res; - } - } - - private List faces; - - public MPolyFaceImpl(MPolyFaceType type) { - super(type); - } - - @Override - public void addFace(FaceData face) { - if (faces == null) { - faces = new ArrayList(); - } - faces.add(face); - } - - @Override - public MData getData(int start, int end) { - return this; // hack? - } - - @Override - public List getFaces() { - return faces; - } - - @Override - public void parse(Iterator values) { - // System.out.println("parsing poly faces: " + values); - new Parser(values).parse(); - } - - @Override - public String toString() { - StringBuffer result = new StringBuffer(); - result.append(getType().getName()); - if (faces == null) { - result.append(" "); - result.append(faces); - } else { - for (FaceData fd : faces) { - result.append(" "); - result.append(fd); - } - } - return result.toString(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MStringImpl.java b/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MStringImpl.java deleted file mode 100644 index 548c74d..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/maya/values/impl/MStringImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.importers.maya.values.impl; - -import java.util.Iterator; - -import com.javafx.experiments.importers.maya.types.MStringType; -import com.javafx.experiments.importers.maya.values.MString; - -public class MStringImpl extends MDataImpl implements MString { - - private String value; - - public MStringImpl(MStringType type) { - super(type); - } - - @Override - public String get() { - return value; - } - - @Override - public void parse(Iterator values) { - value = values.next(); - } - - @Override - public void set(String str) { - value = str; - } - - @Override - public String toString() { - String result = getType().getName(); - result += " " + value; - return result; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/FloatArrayList.java b/gui/src/main/java/com/javafx/experiments/importers/obj/FloatArrayList.java deleted file mode 100644 index 70db3e9..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/FloatArrayList.java +++ /dev/null @@ -1,1284 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import java.util.AbstractList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.RandomAccess; -import java.util.Vector; - -/** - * Resizable-array implementation of the List<Float> interface. - * Implements all optional list operations, and doesn't permit nulls. - * In addition to implementing the List interface, this class provides - * methods to manipulate the size of the array that is used internally to store - * the list. (This class is roughly equivalent to Vector, except that - * it is unsynchronized.) - *

- *

- * The size, isEmpty, get, set, - * iterator, and listIterator operations run in constant time. - * The add operation runs in amortized constant time, that is, - * adding n elements requires O(n) time. All of the other operations run in - * linear time (roughly speaking). The constant factor is low compared to that - * for the LinkedList implementation. - *

- *

- * Each ArrayList instance has a capacity. The capacity is the - * size of the array used to store the elements in the list. It is always at - * least as large as the list size. As elements are added to an ArrayList, its - * capacity grows automatically. The details of the growth policy are not - * specified beyond the fact that adding an element has constant amortized time - * cost. - *

- *

- * An application can increase the capacity of an ArrayList instance - * before adding a large number of elements using the ensureCapacity - * operation. This may reduce the amount of incremental reallocation. - *

- *

- * Note that this implementation is not synchronized. If - * multiple threads access an ArrayList instance concurrently, and at - * least one of the threads modifies the list structurally, it must be - * synchronized externally. (A structural modification is any operation that - * adds or deletes one or more elements, or explicitly resizes the backing - * array; merely setting the value of an element is not a structural - * modification.) This is typically accomplished by synchronizing on some object - * that naturally encapsulates the list. - *

- * If no such object exists, the list should be "wrapped" using the - * {@link Collections#synchronizedList Collections.synchronizedList} method. - * This is best done at creation time, to prevent accidental unsynchronized - * access to the list: - * - *

- *   List list = Collections.synchronizedList(new ArrayList(...));
- * 
- *

- *

- * The iterators returned by this class's - * {@link #iterator() iterator} and {@link #listIterator(int) listIterator} - * methods are fail-fast: if the list is structurally modified at any - * time after the iterator is created, in any way except through the iterator's - * own {@link ListIterator#remove() remove} or {@link ListIterator#add(Object) - * add} methods, the iterator will throw a - * {@link ConcurrentModificationException}. Thus, in the face of concurrent - * modification, the iterator fails quickly and cleanly, rather than risking - * arbitrary, non-deterministic behavior at an undetermined time in the future. - *

- *

- * Note that the fail-fast behavior of an iterator cannot be guaranteed as it - * is, generally speaking, impossible to make any hard guarantees in the - * presence of unsynchronized concurrent modification. Fail-fast iterators throw - * {@code - * ConcurrentModificationException} on a best-effort basis. Therefore, it would - * be wrong to write a program that depended on this exception for its - * correctness: the fail-fast behavior of iterators should be used only to - * detect bugs. - *

- *

- * This class is a member of the - * Java - * Collections Framework. - * - * @see Collection - * @see List - * @see LinkedList - * @see Vector - * - * TODO replace with ObservableFloatArray - */ -public class FloatArrayList extends AbstractList - implements List, RandomAccess, Cloneable, java.io.Serializable { - - /** An optimized version of AbstractList.Itr */ - private class Itr implements Iterator { - int cursor; // index of next element to return - int expectedModCount = modCount; - int lastRet = -1; // index of last element returned; -1 if no such - - @Override - public boolean hasNext() { - return cursor != size; - } - - @Override - public Float next() { - checkForComodification(); - int i = cursor; - if (i >= size) { - throw new NoSuchElementException(); - } - float[] elementData = FloatArrayList.this.elementData; - if (i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i + 1; - return elementData[lastRet = i]; - } - - @Override - public void remove() { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - FloatArrayList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - } - - /** An optimized version of AbstractList.ListItr */ - private class ListItr extends Itr implements ListIterator { - ListItr(int index) { - super(); - cursor = index; - } - - @Override - public void add(Float e) { - checkForComodification(); - - try { - int i = cursor; - FloatArrayList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasPrevious() { - return cursor != 0; - } - - @Override - public int nextIndex() { - return cursor; - } - - @Override - public Float previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) { - throw new NoSuchElementException(); - } - float[] elementData = FloatArrayList.this.elementData; - if (i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i; - return elementData[lastRet = i]; - } - - @Override - public int previousIndex() { - return cursor - 1; - } - - @Override - public void set(Float e) { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - FloatArrayList.this.set(lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - } - - private class SubList extends FloatArrayList implements RandomAccess { - private static final long serialVersionUID = 1L; - int size; - private final int offset; - private final FloatArrayList parent; - private final int parentOffset; - - SubList(FloatArrayList parent, int offset, int fromIndex, int toIndex) { - this.parent = parent; - this.parentOffset = fromIndex; - this.offset = offset + fromIndex; - this.size = toIndex - fromIndex; - this.modCount = FloatArrayList.this.modCount; - } - - @Override - public void add(int index, Float e) { - rangeCheckForAdd(index); - checkForComodification(); - parent.add(parentOffset + index, e); - this.modCount = parent.modCount; - this.size++; - } - - @Override - public boolean addAll(Collection c) { - return addAll(this.size, c); - } - - @Override - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - int cSize = c.size(); - if (cSize == 0) { - return false; - } - - checkForComodification(); - parent.addAll(parentOffset + index, c); - this.modCount = parent.modCount; - this.size += cSize; - return true; - } - - @Override - public Float get(int index) { - rangeCheck(index); - checkForComodification(); - return FloatArrayList.this.elementData(offset + index); - } - - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public ListIterator listIterator(final int index) { - checkForComodification(); - rangeCheckForAdd(index); - final int offset = this.offset; - - return new ListIterator() { - int cursor = index; - int expectedModCount = FloatArrayList.this.modCount; - int lastRet = -1; - - @Override - public void add(Float e) { - checkForComodification(); - - try { - int i = cursor; - FloatArrayList.SubList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = FloatArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - return cursor != FloatArrayList.SubList.this.size; - } - - @Override - public boolean hasPrevious() { - return cursor != 0; - } - - @Override - public Float next() { - checkForComodification(); - int i = cursor; - if (i >= FloatArrayList.SubList.this.size) { - throw new NoSuchElementException(); - } - float[] elementData = FloatArrayList.this.elementData; - if (offset + i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i + 1; - return elementData[offset + (lastRet = i)]; - } - - @Override - public int nextIndex() { - return cursor; - } - - @Override - public Float previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) { - throw new NoSuchElementException(); - } - float[] elementData = FloatArrayList.this.elementData; - if (offset + i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i; - return elementData[offset + (lastRet = i)]; - } - - @Override - public int previousIndex() { - return cursor - 1; - } - - @Override - public void remove() { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - FloatArrayList.SubList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = FloatArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public void set(Float e) { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - FloatArrayList.this.set(offset + lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (expectedModCount != FloatArrayList.this.modCount) { - throw new ConcurrentModificationException(); - } - } - }; - } - - @Override - public Float remove(int index) { - rangeCheck(index); - checkForComodification(); - Float result = parent.remove(parentOffset + index); - this.modCount = parent.modCount; - this.size--; - return result; - } - - @Override - public Float set(int index, Float e) { - rangeCheck(index); - checkForComodification(); - Float oldValue = FloatArrayList.this.elementData(offset + index); - FloatArrayList.this.elementData[offset + index] = e; - return oldValue; - } - - @Override - public int size() { - checkForComodification(); - return this.size; - } - - @Override - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new FloatArrayList.SubList(this, offset, fromIndex, toIndex); - } - - @Override - public float[] toFloatArray() { - float[] res = new float[size]; - System.arraycopy(elementData, offset, res, 0, size); - return res; - } - - @Override - protected void removeRange(int fromIndex, int toIndex) { - checkForComodification(); - parent.removeRange(parentOffset + fromIndex, - parentOffset + toIndex); - this.modCount = parent.modCount; - this.size -= toIndex - fromIndex; - } - - private void checkForComodification() { - if (FloatArrayList.this.modCount != this.modCount) { - throw new ConcurrentModificationException(); - } - } - - private String outOfBoundsMsg(int index) { - return "Index: " + index + ", Size: " + this.size; - } - - private void rangeCheck(int index) { - if (index < 0 || index >= this.size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - private void rangeCheckForAdd(int index) { - if (index < 0 || index > this.size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - } - - /** - * The maximum size of array to allocate. Some VMs reserve some header words - * in an array. Attempts to allocate larger arrays may result in - * OutOfMemoryError: Requested array size exceeds VM limit - */ - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - private static final long serialVersionUID = 1L; - - static void subListRangeCheck(int fromIndex, int toIndex, int size) { - if (fromIndex < 0) { - throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); - } - if (toIndex > size) { - throw new IndexOutOfBoundsException("toIndex = " + toIndex); - } - if (fromIndex > toIndex) { - throw new IllegalArgumentException("fromIndex(" + fromIndex - + ") > toIndex(" + toIndex - + ")"); - } - } - - private static int hugeCapacity(int minCapacity) { - if (minCapacity < 0) { - throw new OutOfMemoryError(); - } - return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE - : MAX_ARRAY_SIZE; - } - - /** - * The array buffer into which the elements of the ArrayList are stored. The - * capacity of the ArrayList is the length of this array buffer. - */ - private transient float[] elementData; - - /** - * The size of the ArrayList (the number of elements it contains). - * - * @serial - */ - private int size; - - /** Constructs an empty list with an initial capacity of ten. */ - public FloatArrayList() { - this(10); - } - - /** - * Constructs a list containing the elements of the specified collection, in - * the order they are returned by the collection's iterator. - * - * @param c - * the collection whose elements are to be placed into this list - * @throws NullPointerException - * if the specified collection is null - */ - public FloatArrayList(Collection c) { - elementData = new float[c.size()]; - int i = 0; - for (Float d : c) { - elementData[i] = d; - i++; - } - size = elementData.length; - } - - /** - * Constructs an empty list with the specified initial capacity. - * - * @param initialCapacity - * the initial capacity of the list - * @throws IllegalArgumentException - * if the specified initial capacity is negative - */ - public FloatArrayList(int initialCapacity) { - super(); - if (initialCapacity < 0) { - throw new IllegalArgumentException("Illegal Capacity: " - + initialCapacity); - } - this.elementData = new float[initialCapacity]; - } - - /** - * Appends the specified element to the end of this list. - * - * @param e - * element to be appended to this list - * @return true (as specified by {@link Collection#add}) - */ - @Override - public boolean add(Float e) { - ensureCapacityInternal(size + 1); // Increments modCount!! - elementData[size++] = e; - return true; - } - - /** - * Inserts the specified element at the specified position in this list. - * Shifts the element currently at that position (if any) and any subsequent - * elements to the right (adds one to their indices). - * - * @param index - * index at which the specified element is to be inserted - * @param element - * element to be inserted - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public void add(int index, Float element) { - rangeCheckForAdd(index); - - ensureCapacityInternal(size + 1); // Increments modCount!! - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - elementData[index] = element; - size++; - } - - /** - * Appends all of the elements in the specified collection to the end of - * this list, in the order that they are returned by the specified - * collection's Iterator. The behavior of this operation is undefined if the - * specified collection is modified while the operation is in progress. - * (This implies that the behavior of this call is undefined if the - * specified collection is this list, and this list is nonempty.) - * - * @param c - * collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws NullPointerException - * if the specified collection is null - */ - @Override - public boolean addAll(Collection c) { - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - System.arraycopy(a, 0, elementData, size, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Inserts all of the elements in the specified collection into this list, - * starting at the specified position. Shifts the element currently at that - * position (if any) and any subsequent elements to the right (increases - * their indices). The new elements will appear in the list in the order - * that they are returned by the specified collection's iterator. - * - * @param index - * index at which to insert the first element from the specified - * collection - * @param c - * collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws IndexOutOfBoundsException - * {@inheritDoc} - * @throws NullPointerException - * if the specified collection is null - */ - @Override - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - - int numMoved = size - index; - if (numMoved > 0) { - System.arraycopy(elementData, index, elementData, index + numNew, - numMoved); - } - - System.arraycopy(a, 0, elementData, index, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Removes all of the elements from this list. The list will be empty after - * this call returns. - */ - @Override - public void clear() { - modCount++; - - // Forget the items completely - for (int i = 0; i < size; i++) { - elementData[i] = 0; - } - - size = 0; - } - - /** - * Returns a shallow copy of this ArrayList instance. (The elements - * themselves are not copied.) - * - * @return a clone of this ArrayList instance - */ - @Override - public Object clone() { - try { - FloatArrayList v = (FloatArrayList) super.clone(); - v.elementData = Arrays.copyOf(elementData, size); - v.modCount = 0; - return v; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Returns true if this list contains the specified element. More - * formally, returns true if and only if this list contains at - * least one element e such that - * (o==null ? e==null : o.equals(e)). - * - * @param o - * element whose presence in this list is to be tested - * @return true if this list contains the specified element - */ - @Override - public boolean contains(Object o) { - return indexOf(o) >= 0; - } - - /** - * Increases the capacity of this ArrayList instance, if necessary, - * to ensure that it can hold at least the number of elements specified by - * the minimum capacity argument. - * - * @param minCapacity - * the desired minimum capacity - */ - public void ensureCapacity(int minCapacity) { - if (minCapacity > 0) { - ensureCapacityInternal(minCapacity); - } - } - - /** - * Returns the element at the specified position in this list. - * - * @param index - * index of the element to return - * @return the element at the specified position in this list - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Float get(int index) { - rangeCheck(index); - - return elementData(index); - } - - // Positional Access Operations - - /** - * Returns the index of the first occurrence of the specified element in - * this list, or -1 if this list does not contain the element. More - * formally, returns the lowest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - @Override - public int indexOf(Object o) { - if (o instanceof Float) { - for (int i = 0; i < size; i++) { - if (o.equals(elementData[i])) { - return i; - } - } - } - return -1; - } - - /** - * Returns true if this list contains no elements. - * - * @return true if this list contains no elements - */ - @Override - public boolean isEmpty() { - return size == 0; - } - - /** - * Returns an iterator over the elements in this list in proper sequence. - *

- *

- * The returned iterator is fail-fast. - * - * @return an iterator over the elements in this list in proper sequence - */ - @Override - public Iterator iterator() { - return new Itr(); - } - - /** - * Returns the index of the last occurrence of the specified element in this - * list, or -1 if this list does not contain the element. More formally, - * returns the highest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - @Override - public int lastIndexOf(Object o) { - if (o instanceof Float) { - for (int i = size - 1; i >= 0; i--) { - if (o.equals(elementData[i])) { - return i; - } - } - } - return -1; - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence). - *

- *

- * The returned list iterator is fail-fast. - * - * @see #listIterator(int) - */ - @Override - public ListIterator listIterator() { - return new ListItr(0); - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence), starting at the specified position in the list. The specified - * index indicates the first element that would be returned by an initial - * call to {@link ListIterator#next next}. An initial call to - * {@link ListIterator#previous previous} would return the element with the - * specified index minus one. - *

- *

- * The returned list iterator is fail-fast. - * - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public ListIterator listIterator(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Index: " + index); - } - return new ListItr(index); - } - - /** - * Removes the element at the specified position in this list. Shifts any - * subsequent elements to the left (subtracts one from their indices). - * - * @param index - * the index of the element to be removed - * @return the element that was removed from the list - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Float remove(int index) { - rangeCheck(index); - - modCount++; - Float oldValue = elementData(index); - - int numMoved = size - index - 1; - if (numMoved > 0) { - System.arraycopy(elementData, index + 1, elementData, index, - numMoved); - } - elementData[--size] = 0; // Forget the item completely - - return oldValue; - } - - /** - * Removes the first occurrence of the specified element from this list, if - * it is present. If the list does not contain the element, it is unchanged. - * More formally, removes the element with the lowest index i such - * that - * (o==null ? get(i)==null : o.equals(get(i))) - * (if such an element exists). Returns true if this list contained - * the specified element (or equivalently, if this list changed as a result - * of the call). - * - * @param o - * element to be removed from this list, if present - * @return true if this list contained the specified element - */ - @Override - public boolean remove(Object o) { - if (o instanceof Float) { - for (int index = 0; index < size; index++) { - if (o.equals(elementData[index])) { - fastRemove(index); - return true; - } - } - } - return false; - } - - /** - * Removes from this list all of its elements that are contained in the - * specified collection. - * - * @param c - * collection containing elements to be removed from this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException - * if the class of an element of this list is incompatible with - * the specified collection (optional) - * @throws NullPointerException - * if this list contains a null element and the specified - * collection does not permit null elements (optional), or if - * the specified collection is null - * @see Collection#contains(Object) - */ - @Override - public boolean removeAll(Collection c) { - return batchRemove(c, false); - } - - /** - * Retains only the elements in this list that are contained in the - * specified collection. In other words, removes from this list all of its - * elements that are not contained in the specified collection. - * - * @param c - * collection containing elements to be retained in this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException - * if the class of an element of this list is incompatible with - * the specified collection (optional) - * @throws NullPointerException - * if this list contains a null element and the specified - * collection does not permit null elements (optional), or if - * the specified collection is null - * @see Collection#contains(Object) - */ - @Override - public boolean retainAll(Collection c) { - return batchRemove(c, true); - } - - /** - * Replaces the element at the specified position in this list with the - * specified element. - * - * @param index - * index of the element to replace - * @param element - * element to be stored at the specified position - * @return the element previously at the specified position - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Float set(int index, Float element) { - rangeCheck(index); - - Float oldValue = elementData(index); - elementData[index] = element; - return oldValue; - } - - /** - * Returns the number of elements in this list. - * - * @return the number of elements in this list - */ - @Override - public int size() { - return size; - } - - /** - * Returns a view of the portion of this list between the specified - * {@code fromIndex}, inclusive, and {@code - * toIndex}, exclusive. (If {@code fromIndex} and {@code toIndex} are equal, - * the returned list is empty.) The returned list is backed by this list, so - * non-structural changes in the returned list are reflected in this list, - * and vice-versa. The returned list supports all of the optional list - * operations. - *

- *

- * This method eliminates the need for explicit range operations (of the - * sort that commonly exist for arrays). Any operation that expects a list - * can be used as a range operation by passing a subList view instead of a - * whole list. For example, the following idiom removes a range of elements - * from a list: - * - *

-     * list.subList(from, to)
-     *     .clear();
-     * 
- * - * Similar idioms may be constructed for {@link #indexOf(Object)} and - * {@link #lastIndexOf(Object)}, and all of the algorithms in the - * {@link Collections} class can be applied to a subList. - *

- *

- * The semantics of the list returned by this method become undefined if the - * backing list (i.e., this list) is structurally modified in any way - * other than via the returned list. (Structural modifications are those - * that change the size of this list, or otherwise perturb it in such a - * fashion that iterations in progress may yield incorrect results.) - * - * @throws IndexOutOfBoundsException - * {@inheritDoc} - * @throws IllegalArgumentException - * {@inheritDoc} - */ - @Override - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new FloatArrayList.SubList(this, 0, fromIndex, toIndex); - } - - /** - * Returns an array containing all of the elements in this list in proper - * sequence (from first to last element). - *

- *

- * The returned array will be "safe" in that no references to it are - * maintained by this list. (In other words, this method must allocate a new - * array). The caller is thus free to modify the returned array. - *

- *

- * This method acts as bridge between array-based and collection-based APIs. - * - * @return an array containing all of the elements in this list in proper - * sequence - */ - @Override - public Object[] toArray() { - Float[] array = new Float[size]; - for (int i = 0; i < size; i++) { - array[i] = elementData[i]; - } - return array; - } - - /** - * Returns an array containing all of the elements in this list in proper - * sequence (from first to last element); the runtime type of the returned - * array is that of the specified array. If the list fits in the specified - * array, it is returned therein. Otherwise, a new array is allocated with - * the runtime type of the specified array and the size of this list. - *

- *

- * If the list fits in the specified array with room to spare (i.e., the - * array has more elements than the list), the element in the array - * immediately following the end of the collection is set to null. - * (This is useful in determining the length of the list only if the - * caller knows that the list does not contain any null elements.) - * - * @param a - * the array into which the elements of the list are to be - * stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose. - * @return an array containing the elements of the list - * @throws ArrayStoreException - * if the runtime type of the specified array is not a supertype - * of the runtime type of every element in this list - * @throws NullPointerException - * if the specified array is null - */ - @SuppressWarnings("unchecked") - @Override - public T[] toArray(T[] a) { - if (a.length < size) { - // Make a new array of a's runtime type, but my contents: - return (T[]) Arrays.copyOf(toArray(), size, a.getClass()); - } - System.arraycopy(elementData, 0, a, 0, size); - if (a.length > size) { - a[size] = null; - } - return a; - } - - public float[] toFloatArray() { - float[] res = new float[size]; - System.arraycopy(elementData, 0, res, 0, size); - return res; - } - - /** - * Trims the capacity of this ArrayList instance to be the list - * current size. An application can use this operation to minimize the - * storage of an ArrayList instance. - */ - public void trimToSize() { - modCount++; - int oldCapacity = elementData.length; - if (size < oldCapacity) { - elementData = Arrays.copyOf(elementData, size); - } - } - - /** - * Removes from this list all of the elements whose index is between - * {@code fromIndex}, inclusive, and {@code - * toIndex}, exclusive. Shifts any succeeding elements to the left (reduces - * their index). This call shortens the list by - * {@code (toIndex - fromIndex)} elements. (If {@code toIndex==fromIndex}, - * this operation has no effect.) - * - * @throws IndexOutOfBoundsException - * if {@code fromIndex} or {@code toIndex} is out of range - * ({@code fromIndex < 0 - * || fromIndex >= size() || toIndex > size() || toIndex < fromIndex}) - */ - @Override - protected void removeRange(int fromIndex, int toIndex) { - modCount++; - int numMoved = size - toIndex; - System.arraycopy(elementData, toIndex, elementData, fromIndex, - numMoved); - - // Forget the item completely - int newSize = size - (toIndex - fromIndex); - while (size != newSize) { - elementData[--size] = 0; - } - } - - Float elementData(int index) { - return elementData[index]; - } - - private boolean batchRemove(Collection c, boolean complement) { - final float[] elementData = this.elementData; - int r = 0, w = 0; - boolean modified = false; - try { - for (; r < size; r++) { - if (c.contains(elementData[r]) == complement) { - elementData[w++] = elementData[r]; - } - } - } finally { - // Preserve behavioral compatibility with AbstractCollection, - // even if c.contains() throws. - if (r != size) { - System.arraycopy(elementData, r, elementData, w, size - r); - w += size - r; - } - if (w != size) { - for (int i = w; i < size; i++) { - elementData[i] = 0; - } - modCount += size - w; - size = w; - modified = true; - } - } - return modified; - } - - private void ensureCapacityInternal(int minCapacity) { - modCount++; - // overflow-conscious code - if (minCapacity - elementData.length > 0) { - grow(minCapacity); - } - } - - /* - * Private remove method that skips bounds checking and does not - * return the value removed. - */ - private void fastRemove(int index) { - modCount++; - int numMoved = size - index - 1; - if (numMoved > 0) { - System.arraycopy(elementData, index + 1, elementData, index, - numMoved); - } - elementData[--size] = 0; // Forget the item completely - } - - /** - * Increases the capacity to ensure that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity - * the desired minimum capacity - */ - private void grow(int minCapacity) { - // overflow-conscious code - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + (oldCapacity >> 1); - if (newCapacity - minCapacity < 0) { - newCapacity = minCapacity; - } - if (newCapacity - MAX_ARRAY_SIZE > 0) { - newCapacity = hugeCapacity(minCapacity); - } - // minCapacity is usually close to size, so this is a win: - elementData = Arrays.copyOf(elementData, newCapacity); - } - - /** - * Constructs an IndexOutOfBoundsException detail message. Of the many - * possible refactorings of the error handling code, this "outlining" - * performs best with both server and client VMs. - */ - private String outOfBoundsMsg(int index) { - return "Index: " + index + ", Size: " + size; - } - - /** - * Checks if the given index is in range. If not, throws an appropriate - * runtime exception. This method does *not* check if the index is negative: - * It is always used immediately prior to an array access, which throws an - * ArrayIndexOutOfBoundsException if index is negative. - */ - private void rangeCheck(int index) { - if (index >= size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - /** A version of rangeCheck used by add and addAll. */ - private void rangeCheckForAdd(int index) { - if (index > size || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - /** - * Reconstitute the ArrayList instance from a stream (that is, - * deserialize it). - */ - private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, - ClassNotFoundException { - // Read in size, and any hidden stuff - s.defaultReadObject(); - - // Read in array length and allocate array - int arrayLength = s.readInt(); - float[] a = elementData = new float[arrayLength]; - - // Read in all elements in the proper order. - for (int i = 0; i < size; i++) { - a[i] = (Float) s.readObject(); - } - } - - /** - * Save the state of the ArrayList instance to a stream (that is, - * serialize it). - * - * @serialData The length of the array backing the ArrayList - * instance is emitted (int), followed by all of its elements - * (each an Object) in the proper order. - */ - private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { - // Write out element count, and any hidden stuff - int expectedModCount = modCount; - s.defaultWriteObject(); - - // Write out array length - s.writeInt(elementData.length); - - // Write out all elements in the proper order. - for (int i = 0; i < size; i++) { - s.writeObject(elementData[i]); - } - - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/IntegerArrayList.java b/gui/src/main/java/com/javafx/experiments/importers/obj/IntegerArrayList.java deleted file mode 100644 index 768fbd7..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/IntegerArrayList.java +++ /dev/null @@ -1,1289 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import java.util.AbstractList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.NoSuchElementException; -import java.util.RandomAccess; -import java.util.Vector; - -/** - * Resizable-array implementation of the List<Integer> interface. - * Implements all optional list operations, and doesn't permit nulls. - * In addition to implementing the List interface, this class provides - * methods to manipulate the size of the array that is used internally to store - * the list. (This class is roughly equivalent to Vector, except that - * it is unsynchronized.) - *

- *

- * The size, isEmpty, get, set, - * iterator, and listIterator operations run in constant time. - * The add operation runs in amortized constant time, that is, - * adding n elements requires O(n) time. All of the other operations run in - * linear time (roughly speaking). The constant factor is low compared to that - * for the LinkedList implementation. - *

- *

- * Each ArrayList instance has a capacity. The capacity is the - * size of the array used to store the elements in the list. It is always at - * least as large as the list size. As elements are added to an ArrayList, its - * capacity grows automatically. The details of the growth policy are not - * specified beyond the fact that adding an element has constant amortized time - * cost. - *

- *

- * An application can increase the capacity of an ArrayList instance - * before adding a large number of elements using the ensureCapacity - * operation. This may reduce the amount of incremental reallocation. - *

- *

- * Note that this implementation is not synchronized. If - * multiple threads access an ArrayList instance concurrently, and at - * least one of the threads modifies the list structurally, it must be - * synchronized externally. (A structural modification is any operation that - * adds or deletes one or more elements, or explicitly resizes the backing - * array; merely setting the value of an element is not a structural - * modification.) This is typically accomplished by synchronizing on some object - * that naturally encapsulates the list. - *

- * If no such object exists, the list should be "wrapped" using the - * {@link Collections#synchronizedList Collections.synchronizedList} method. - * This is best done at creation time, to prevent accidental unsynchronized - * access to the list: - * - *

- *   List list = Collections.synchronizedList(new ArrayList(...));
- * 
- *

- *

- * The iterators returned by this class's - * {@link #iterator() iterator} and {@link #listIterator(int) listIterator} - * methods are fail-fast: if the list is structurally modified at any - * time after the iterator is created, in any way except through the iterator's - * own {@link ListIterator#remove() remove} or {@link ListIterator#add(Object) - * add} methods, the iterator will throw a - * {@link ConcurrentModificationException}. Thus, in the face of concurrent - * modification, the iterator fails quickly and cleanly, rather than risking - * arbitrary, non-deterministic behavior at an undetermined time in the future. - *

- *

- * Note that the fail-fast behavior of an iterator cannot be guaranteed as it - * is, generally speaking, impossible to make any hard guarantees in the - * presence of unsynchronized concurrent modification. Fail-fast iterators throw - * {@code - * ConcurrentModificationException} on a best-effort basis. Therefore, it would - * be wrong to write a program that depended on this exception for its - * correctness: the fail-fast behavior of iterators should be used only to - * detect bugs. - *

- *

- * This class is a member of the - * Java - * Collections Framework. - * - * @see Collection - * @see List - * @see LinkedList - * @see Vector - * - * TODO replace with ObservableIntegerArray - */ -public class IntegerArrayList extends AbstractList implements - List, RandomAccess, Cloneable, java.io.Serializable { - - /** An optimized version of AbstractList.Itr */ - private class Itr implements Iterator { - int cursor; // index of next element to return - int expectedModCount = modCount; - int lastRet = -1; // index of last element returned; -1 if no such - - @Override - public boolean hasNext() { - return cursor != size; - } - - @Override - public Integer next() { - checkForComodification(); - int i = cursor; - if (i >= size) { - throw new NoSuchElementException(); - } - int[] elementData = IntegerArrayList.this.elementData; - if (i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i + 1; - return elementData[lastRet = i]; - } - - @Override - public void remove() { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - IntegerArrayList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - } - } - - /** An optimized version of AbstractList.ListItr */ - private class ListItr extends Itr implements ListIterator { - ListItr(int index) { - super(); - cursor = index; - } - - @Override - public void add(Integer e) { - checkForComodification(); - - try { - int i = cursor; - IntegerArrayList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasPrevious() { - return cursor != 0; - } - - @Override - public int nextIndex() { - return cursor; - } - - @Override - public Integer previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) { - throw new NoSuchElementException(); - } - int[] elementData = IntegerArrayList.this.elementData; - if (i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i; - return elementData[lastRet = i]; - } - - @Override - public int previousIndex() { - return cursor - 1; - } - - @Override - public void set(Integer e) { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - IntegerArrayList.this.set(lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - } - - private class SubList extends IntegerArrayList implements RandomAccess { - private static final long serialVersionUID = 1L; - int size; - private final int offset; - private final IntegerArrayList parent; - private final int parentOffset; - - SubList(IntegerArrayList parent, int offset, int fromIndex, - int toIndex) { - this.parent = parent; - this.parentOffset = fromIndex; - this.offset = offset + fromIndex; - this.size = toIndex - fromIndex; - this.modCount = IntegerArrayList.this.modCount; - } - - @Override - public void add(int index, Integer e) { - rangeCheckForAdd(index); - checkForComodification(); - parent.add(parentOffset + index, e); - this.modCount = parent.modCount; - this.size++; - } - - @Override - public boolean addAll(Collection c) { - return addAll(this.size, c); - } - - @Override - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - int cSize = c.size(); - if (cSize == 0) { - return false; - } - - checkForComodification(); - parent.addAll(parentOffset + index, c); - this.modCount = parent.modCount; - this.size += cSize; - return true; - } - - @Override - public Integer get(int index) { - rangeCheck(index); - checkForComodification(); - return IntegerArrayList.this.elementData(offset + index); - } - - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public ListIterator listIterator(final int index) { - checkForComodification(); - rangeCheckForAdd(index); - final int offset = this.offset; - - return new ListIterator() { - int cursor = index; - int expectedModCount = IntegerArrayList.this.modCount; - int lastRet = -1; - - @Override - public void add(Integer e) { - checkForComodification(); - - try { - int i = cursor; - IntegerArrayList.SubList.this.add(i, e); - cursor = i + 1; - lastRet = -1; - expectedModCount = IntegerArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public boolean hasNext() { - return cursor != IntegerArrayList.SubList.this.size; - } - - @Override - public boolean hasPrevious() { - return cursor != 0; - } - - @Override - public Integer next() { - checkForComodification(); - int i = cursor; - if (i >= IntegerArrayList.SubList.this.size) { - throw new NoSuchElementException(); - } - int[] elementData = IntegerArrayList.this.elementData; - if (offset + i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i + 1; - return elementData[offset + (lastRet = i)]; - } - - @Override - public int nextIndex() { - return cursor; - } - - @Override - public Integer previous() { - checkForComodification(); - int i = cursor - 1; - if (i < 0) { - throw new NoSuchElementException(); - } - int[] elementData = IntegerArrayList.this.elementData; - if (offset + i >= elementData.length) { - throw new ConcurrentModificationException(); - } - cursor = i; - return elementData[offset + (lastRet = i)]; - } - - @Override - public int previousIndex() { - return cursor - 1; - } - - @Override - public void remove() { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - IntegerArrayList.SubList.this.remove(lastRet); - cursor = lastRet; - lastRet = -1; - expectedModCount = IntegerArrayList.this.modCount; - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - @Override - public void set(Integer e) { - if (lastRet < 0) { - throw new IllegalStateException(); - } - checkForComodification(); - - try { - IntegerArrayList.this.set(offset + lastRet, e); - } catch (IndexOutOfBoundsException ex) { - throw new ConcurrentModificationException(); - } - } - - final void checkForComodification() { - if (expectedModCount != IntegerArrayList.this.modCount) { - throw new ConcurrentModificationException(); - } - } - }; - } - - @Override - public Integer remove(int index) { - rangeCheck(index); - checkForComodification(); - Integer result = parent.remove(parentOffset + index); - this.modCount = parent.modCount; - this.size--; - return result; - } - - @Override - public Integer set(int index, Integer e) { - rangeCheck(index); - checkForComodification(); - Integer oldValue = IntegerArrayList.this.elementData(offset - + index); - IntegerArrayList.this.elementData[offset + index] = e; - return oldValue; - } - - @Override - public int size() { - checkForComodification(); - return this.size; - } - - @Override - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new IntegerArrayList.SubList(this, offset, fromIndex, - toIndex); - } - - @Override - public int[] toIntArray() { - int[] res = new int[size]; - System.arraycopy(elementData, offset, res, 0, size); - return res; - } - - @Override - protected void removeRange(int fromIndex, int toIndex) { - checkForComodification(); - parent.removeRange(parentOffset + fromIndex, - parentOffset + toIndex); - this.modCount = parent.modCount; - this.size -= toIndex - fromIndex; - } - - private void checkForComodification() { - if (IntegerArrayList.this.modCount != this.modCount) { - throw new ConcurrentModificationException(); - } - } - - private String outOfBoundsMsg(int index) { - return "Index: " + index + ", Size: " + this.size; - } - - private void rangeCheck(int index) { - if (index < 0 || index >= this.size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - private void rangeCheckForAdd(int index) { - if (index < 0 || index > this.size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - } - - /** - * The maximum size of array to allocate. Some VMs reserve some header words - * in an array. Attempts to allocate larger arrays may result in - * OutOfMemoryError: Requested array size exceeds VM limit - */ - private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; - - private static final long serialVersionUID = 1L; - - static void subListRangeCheck(int fromIndex, int toIndex, int size) { - if (fromIndex < 0) { - throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); - } - if (toIndex > size) { - throw new IndexOutOfBoundsException("toIndex = " + toIndex); - } - if (fromIndex > toIndex) { - throw new IllegalArgumentException("fromIndex(" + fromIndex - + ") > toIndex(" + toIndex - + ")"); - } - } - - private static int hugeCapacity(int minCapacity) { - if (minCapacity < 0) { - throw new OutOfMemoryError(); - } - return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE - : MAX_ARRAY_SIZE; - } - - /** - * The array buffer into which the elements of the ArrayList are stored. The - * capacity of the ArrayList is the length of this array buffer. - */ - private transient int[] elementData; - - /** - * The size of the ArrayList (the number of elements it contains). - * - * @serial - */ - private int size; - - /** Constructs an empty list with an initial capacity of ten. */ - public IntegerArrayList() { - this(10); - } - - /** - * Constructs a list containing the elements of the specified collection, in - * the order they are returned by the collection's iterator. - * - * @param c - * the collection whose elements are to be placed into this list - * @throws NullPointerException - * if the specified collection is null - */ - public IntegerArrayList(Collection c) { - elementData = new int[c.size()]; - int i = 0; - for (Integer d : c) { - elementData[i] = d; - i++; - } - size = elementData.length; - } - - /** - * Constructs an empty list with the specified initial capacity. - * - * @param initialCapacity - * the initial capacity of the list - * @throws IllegalArgumentException - * if the specified initial capacity is negative - */ - public IntegerArrayList(int initialCapacity) { - super(); - if (initialCapacity < 0) { - throw new IllegalArgumentException("Illegal Capacity: " - + initialCapacity); - } - this.elementData = new int[initialCapacity]; - } - - /** - * Inserts the specified element at the specified position in this list. - * Shifts the element currently at that position (if any) and any subsequent - * elements to the right (adds one to their indices). - * - * @param index - * index at which the specified element is to be inserted - * @param element - * element to be inserted - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public void add(int index, Integer element) { - rangeCheckForAdd(index); - - ensureCapacityInternal(size + 1); // Increments modCount!! - System.arraycopy(elementData, index, elementData, index + 1, - size - index); - elementData[index] = element; - size++; - } - - /** - * Appends the specified element to the end of this list. - * - * @param e - * element to be appended to this list - * @return true (as specified by {@link Collection#add}) - */ - @Override - public boolean add(Integer e) { - ensureCapacityInternal(size + 1); // Increments modCount!! - elementData[size++] = e; - return true; - } - - /** - * Appends all of the elements in the specified collection to the end of - * this list, in the order that they are returned by the specified - * collection's Iterator. The behavior of this operation is undefined if the - * specified collection is modified while the operation is in progress. - * (This implies that the behavior of this call is undefined if the - * specified collection is this list, and this list is nonempty.) - * - * @param c - * collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws NullPointerException - * if the specified collection is null - */ - @Override - public boolean addAll(Collection c) { - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - System.arraycopy(a, 0, elementData, size, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Inserts all of the elements in the specified collection into this list, - * starting at the specified position. Shifts the element currently at that - * position (if any) and any subsequent elements to the right (increases - * their indices). The new elements will appear in the list in the order - * that they are returned by the specified collection's iterator. - * - * @param index - * index at which to insert the first element from the specified - * collection - * @param c - * collection containing elements to be added to this list - * @return true if this list changed as a result of the call - * @throws IndexOutOfBoundsException - * {@inheritDoc} - * @throws NullPointerException - * if the specified collection is null - */ - @Override - public boolean addAll(int index, Collection c) { - rangeCheckForAdd(index); - - Object[] a = c.toArray(); - int numNew = a.length; - ensureCapacityInternal(size + numNew); // Increments modCount - - int numMoved = size - index; - if (numMoved > 0) { - System.arraycopy(elementData, index, elementData, index + numNew, - numMoved); - } - - System.arraycopy(a, 0, elementData, index, numNew); - size += numNew; - return numNew != 0; - } - - /** - * Removes all of the elements from this list. The list will be empty after - * this call returns. - */ - @Override - public void clear() { - modCount++; - - // Forget the items completely - for (int i = 0; i < size; i++) { - elementData[i] = 0; - } - - size = 0; - } - - /** - * Returns a shallow copy of this ArrayList instance. (The elements - * themselves are not copied.) - * - * @return a clone of this ArrayList instance - */ - @Override - public Object clone() { - try { - - IntegerArrayList v = (IntegerArrayList) super.clone(); - v.elementData = Arrays.copyOf(elementData, size); - v.modCount = 0; - return v; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - /** - * Returns true if this list contains the specified element. More - * formally, returns true if and only if this list contains at - * least one element e such that - * (o==null ? e==null : o.equals(e)). - * - * @param o - * element whose presence in this list is to be tested - * @return true if this list contains the specified element - */ - @Override - public boolean contains(Object o) { - return indexOf(o) >= 0; - } - - /** - * Increases the capacity of this ArrayList instance, if necessary, - * to ensure that it can hold at least the number of elements specified by - * the minimum capacity argument. - * - * @param minCapacity - * the desired minimum capacity - */ - public void ensureCapacity(int minCapacity) { - if (minCapacity > 0) { - ensureCapacityInternal(minCapacity); - } - } - - /** - * Returns the element at the specified position in this list. - * - * @param index - * index of the element to return - * @return the element at the specified position in this list - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Integer get(int index) { - rangeCheck(index); - - return elementData(index); - } - - // Positional Access Operations - - /** - * Returns the index of the first occurrence of the specified element in - * this list, or -1 if this list does not contain the element. More - * formally, returns the lowest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - @Override - public int indexOf(Object o) { - if (o instanceof Integer) { - for (int i = 0; i < size; i++) { - if (o.equals(elementData[i])) { - return i; - } - } - } - return -1; - } - - /** - * Returns true if this list contains no elements. - * - * @return true if this list contains no elements - */ - @Override - public boolean isEmpty() { - return size == 0; - } - - /** - * Returns an iterator over the elements in this list in proper sequence. - *

- *

- * The returned iterator is fail-fast. - * - * @return an iterator over the elements in this list in proper sequence - */ - @Override - public Iterator iterator() { - return new Itr(); - } - - /** - * Returns the index of the last occurrence of the specified element in this - * list, or -1 if this list does not contain the element. More formally, - * returns the highest index i such that - * (o==null ? get(i)==null : o.equals(get(i))), - * or -1 if there is no such index. - */ - @Override - public int lastIndexOf(Object o) { - if (o instanceof Integer) { - for (int i = size - 1; i >= 0; i--) { - if (o.equals(elementData[i])) { - return i; - } - } - } - return -1; - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence). - *

- *

- * The returned list iterator is fail-fast. - * - * @see #listIterator(int) - */ - @Override - public ListIterator listIterator() { - return new ListItr(0); - } - - /** - * Returns a list iterator over the elements in this list (in proper - * sequence), starting at the specified position in the list. The specified - * index indicates the first element that would be returned by an initial - * call to {@link ListIterator#next next}. An initial call to - * {@link ListIterator#previous previous} would return the element with the - * specified index minus one. - *

- *

- * The returned list iterator is fail-fast. - * - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public ListIterator listIterator(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Index: " + index); - } - return new ListItr(index); - } - - /** - * Removes the element at the specified position in this list. Shifts any - * subsequent elements to the left (subtracts one from their indices). - * - * @param index - * the index of the element to be removed - * @return the element that was removed from the list - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Integer remove(int index) { - rangeCheck(index); - - modCount++; - Integer oldValue = elementData(index); - - int numMoved = size - index - 1; - if (numMoved > 0) { - System.arraycopy(elementData, index + 1, elementData, index, - numMoved); - } - elementData[--size] = 0; // Forget the item completely - - return oldValue; - } - - /** - * Removes the first occurrence of the specified element from this list, if - * it is present. If the list does not contain the element, it is unchanged. - * More formally, removes the element with the lowest index i such - * that - * (o==null ? get(i)==null : o.equals(get(i))) - * (if such an element exists). Returns true if this list contained - * the specified element (or equivalently, if this list changed as a result - * of the call). - * - * @param o - * element to be removed from this list, if present - * @return true if this list contained the specified element - */ - @Override - public boolean remove(Object o) { - if (o instanceof Integer) { - for (int index = 0; index < size; index++) { - if (o.equals(elementData[index])) { - fastRemove(index); - return true; - } - } - } - return false; - } - - /** - * Removes from this list all of its elements that are contained in the - * specified collection. - * - * @param c - * collection containing elements to be removed from this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException - * if the class of an element of this list is incompatible with - * the specified collection (optional) - * @throws NullPointerException - * if this list contains a null element and the specified - * collection does not permit null elements (optional), or if - * the specified collection is null - * @see Collection#contains(Object) - */ - @Override - public boolean removeAll(Collection c) { - return batchRemove(c, false); - } - - /** - * Retains only the elements in this list that are contained in the - * specified collection. In other words, removes from this list all of its - * elements that are not contained in the specified collection. - * - * @param c - * collection containing elements to be retained in this list - * @return {@code true} if this list changed as a result of the call - * @throws ClassCastException - * if the class of an element of this list is incompatible with - * the specified collection (optional) - * @throws NullPointerException - * if this list contains a null element and the specified - * collection does not permit null elements (optional), or if - * the specified collection is null - * @see Collection#contains(Object) - */ - @Override - public boolean retainAll(Collection c) { - return batchRemove(c, true); - } - - /** - * Replaces the element at the specified position in this list with the - * specified element. - * - * @param index - * index of the element to replace - * @param element - * element to be stored at the specified position - * @return the element previously at the specified position - * @throws IndexOutOfBoundsException - * {@inheritDoc} - */ - @Override - public Integer set(int index, Integer element) { - rangeCheck(index); - - Integer oldValue = elementData(index); - elementData[index] = element; - return oldValue; - } - - /** - * Returns the number of elements in this list. - * - * @return the number of elements in this list - */ - @Override - public int size() { - return size; - } - - /** - * Returns a view of the portion of this list between the specified - * {@code fromIndex}, inclusive, and {@code - * toIndex}, exclusive. (If {@code fromIndex} and {@code toIndex} are equal, - * the returned list is empty.) The returned list is backed by this list, so - * non-structural changes in the returned list are reflected in this list, - * and vice-versa. The returned list supports all of the optional list - * operations. - *

- *

- * This method eliminates the need for explicit range operations (of the - * sort that commonly exist for arrays). Any operation that expects a list - * can be used as a range operation by passing a subList view instead of a - * whole list. For example, the following idiom removes a range of elements - * from a list: - * - *

-     * list.subList(from, to)
-     *     .clear();
-     * 
- * - * Similar idioms may be constructed for {@link #indexOf(Object)} and - * {@link #lastIndexOf(Object)}, and all of the algorithms in the - * {@link Collections} class can be applied to a subList. - *

- *

- * The semantics of the list returned by this method become undefined if the - * backing list (i.e., this list) is structurally modified in any way - * other than via the returned list. (Structural modifications are those - * that change the size of this list, or otherwise perturb it in such a - * fashion that iterations in progress may yield incorrect results.) - * - * @throws IndexOutOfBoundsException - * {@inheritDoc} - * @throws IllegalArgumentException - * {@inheritDoc} - */ - @Override - public List subList(int fromIndex, int toIndex) { - subListRangeCheck(fromIndex, toIndex, size); - return new IntegerArrayList.SubList(this, 0, fromIndex, toIndex); - } - - /** - * Returns an array containing all of the elements in this list in proper - * sequence (from first to last element). - *

- *

- * The returned array will be "safe" in that no references to it are - * maintained by this list. (In other words, this method must allocate a new - * array). The caller is thus free to modify the returned array. - *

- *

- * This method acts as bridge between array-based and collection-based APIs. - * - * @return an array containing all of the elements in this list in proper - * sequence - */ - @Override - public Object[] toArray() { - Integer[] array = new Integer[size]; - for (int i = 0; i < size; i++) { - array[i] = elementData[i]; - } - return array; - } - - /** - * Returns an array containing all of the elements in this list in proper - * sequence (from first to last element); the runtime type of the returned - * array is that of the specified array. If the list fits in the specified - * array, it is returned therein. Otherwise, a new array is allocated with - * the runtime type of the specified array and the size of this list. - *

- *

- * If the list fits in the specified array with room to spare (i.e., the - * array has more elements than the list), the element in the array - * immediately following the end of the collection is set to null. - * (This is useful in determining the length of the list only if the - * caller knows that the list does not contain any null elements.) - * - * @param a - * the array into which the elements of the list are to be - * stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose. - * @return an array containing the elements of the list - * @throws ArrayStoreException - * if the runtime type of the specified array is not a supertype - * of the runtime type of every element in this list - * @throws NullPointerException - * if the specified array is null - */ - - @SuppressWarnings("unchecked") - @Override - public T[] toArray(T[] a) { - if (a.length < size) { - // Make a new array of a's runtime type, but my contents: - return (T[]) Arrays.copyOf(toArray(), size, a.getClass()); - } - System.arraycopy(elementData, 0, a, 0, size); - if (a.length > size) { - a[size] = null; - } - return a; - } - - public int[] toIntArray() { - int[] res = new int[size]; - System.arraycopy(elementData, 0, res, 0, size); - return res; - } - - /** - * Trims the capacity of this ArrayList instance to be the list - * current size. An application can use this operation to minimize the - * storage of an ArrayList instance. - */ - public void trimToSize() { - modCount++; - int oldCapacity = elementData.length; - if (size < oldCapacity) { - elementData = Arrays.copyOf(elementData, size); - } - } - - /** - * Removes from this list all of the elements whose index is between - * {@code fromIndex}, inclusive, and {@code - * toIndex}, exclusive. Shifts any succeeding elements to the left (reduces - * their index). This call shortens the list by - * {@code (toIndex - fromIndex)} elements. (If {@code toIndex==fromIndex}, - * this operation has no effect.) - * - * @throws IndexOutOfBoundsException - * if {@code fromIndex} or {@code toIndex} is out of range - * ({@code fromIndex < 0 - * || fromIndex >= size() || toIndex > size() || toIndex < fromIndex}) - */ - @Override - protected void removeRange(int fromIndex, int toIndex) { - modCount++; - int numMoved = size - toIndex; - System.arraycopy(elementData, toIndex, elementData, fromIndex, - numMoved); - - // Forget the item completely - int newSize = size - (toIndex - fromIndex); - while (size != newSize) { - elementData[--size] = 0; - } - } - - Integer elementData(int index) { - return elementData[index]; - } - - private boolean batchRemove(Collection c, boolean complement) { - final int[] elementData = this.elementData; - int r = 0, w = 0; - boolean modified = false; - try { - for (; r < size; r++) { - if (c.contains(elementData[r]) == complement) { - elementData[w++] = elementData[r]; - } - } - } finally { - // Preserve behavioral compatibility with AbstractCollection, - // even if c.contains() throws. - if (r != size) { - System.arraycopy(elementData, r, elementData, w, size - r); - w += size - r; - } - if (w != size) { - for (int i = w; i < size; i++) { - elementData[i] = 0; - } - modCount += size - w; - size = w; - modified = true; - } - } - return modified; - } - - private void ensureCapacityInternal(int minCapacity) { - modCount++; - // overflow-conscious code - if (minCapacity - elementData.length > 0) { - grow(minCapacity); - } - } - - /* - * Private remove method that skips bounds checking and does not - * return the value removed. - */ - private void fastRemove(int index) { - modCount++; - int numMoved = size - index - 1; - if (numMoved > 0) { - System.arraycopy(elementData, index + 1, elementData, index, - numMoved); - } - elementData[--size] = 0; // Forget the item completely - } - - /** - * Increases the capacity to ensure that it can hold at least the number of - * elements specified by the minimum capacity argument. - * - * @param minCapacity - * the desired minimum capacity - */ - private void grow(int minCapacity) { - // overflow-conscious code - int oldCapacity = elementData.length; - int newCapacity = oldCapacity + (oldCapacity >> 1); - if (newCapacity - minCapacity < 0) { - newCapacity = minCapacity; - } - if (newCapacity - MAX_ARRAY_SIZE > 0) { - newCapacity = hugeCapacity(minCapacity); - } - // minCapacity is usually close to size, so this is a win: - elementData = Arrays.copyOf(elementData, newCapacity); - } - - /** - * Constructs an IndexOutOfBoundsException detail message. Of the many - * possible refactorings of the error handling code, this "outlining" - * performs best with both server and client VMs. - */ - private String outOfBoundsMsg(int index) { - return "Index: " + index + ", Size: " + size; - } - - /** - * Checks if the given index is in range. If not, throws an appropriate - * runtime exception. This method does *not* check if the index is negative: - * It is always used immediately prior to an array access, which throws an - * ArrayIndexOutOfBoundsException if index is negative. - */ - private void rangeCheck(int index) { - if (index >= size) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - /** A version of rangeCheck used by add and addAll. */ - private void rangeCheckForAdd(int index) { - if (index > size || index < 0) { - throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); - } - } - - /** - * Reconstitute the ArrayList instance from a stream (that is, - * deserialize it). - */ - private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, - ClassNotFoundException { - // Read in size, and any hidden stuff - s.defaultReadObject(); - - // Read in array length and allocate array - int arrayLength = s.readInt(); - int[] a = elementData = new int[arrayLength]; - - // Read in all elements in the proper order. - for (int i = 0; i < size; i++) { - a[i] = (Integer) s.readObject(); - } - } - - /** - * Save the state of the ArrayList instance to a stream (that is, - * serialize it). - * - * @serialData The length of the array backing the ArrayList - * instance is emitted (int), followed by all of its elements - * (each an Object) in the proper order. - */ - private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { - // Write out element count, and any hidden stuff - int expectedModCount = modCount; - s.defaultWriteObject(); - - // Write out array length - s.writeInt(elementData.length); - - // Write out all elements in the proper order. - for (int i = 0; i < size; i++) { - s.writeObject(elementData[i]); - } - - if (modCount != expectedModCount) { - throw new ConcurrentModificationException(); - } - - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/MtlReader.java b/gui/src/main/java/com/javafx/experiments/importers/obj/MtlReader.java deleted file mode 100644 index 989f7de..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/MtlReader.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import static com.javafx.experiments.importers.obj.ObjImporter.log; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javafx.scene.image.Image; -import javafx.scene.paint.Color; -import javafx.scene.paint.Material; -import javafx.scene.paint.PhongMaterial; - -/** Reader for OBJ file MTL material files. */ -public class MtlReader { - - private String baseUrl; - - private PhongMaterial material = new PhongMaterial(); - - private Map materials = new HashMap<>(); - private boolean modified = false; - - public MtlReader(String filename, String parentUrl) { - baseUrl = parentUrl.substring(0, parentUrl.lastIndexOf('/') + 1); - String fileUrl = baseUrl + filename; - try { - URL mtlUrl = new URL(fileUrl); - log("Reading material from filename = " + mtlUrl); - read(mtlUrl.openStream()); - } catch (FileNotFoundException ex) { - System.err.println("No material file found for obj. [" + fileUrl - + "]"); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - - public Map getMaterials() { - return Collections.unmodifiableMap(materials); - } - - private void addMaterial(String name) { - if (modified) { - if (!materials.containsKey(name)) { - materials.put(name, material); - } else { - log("This material is already added. Ignoring " + name); - } - material = new PhongMaterial(Color.WHITE); - } - } - - private Image loadImage(String filename) { - filename = baseUrl + filename; - log("Loading image from " + filename); - return new Image(filename); - } - - private void read(InputStream inputStream) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); - String line; - String name = "default"; - while ((line = br.readLine()) != null) { - try { - if (line.isEmpty() || line.startsWith("#")) { - // comments and empty lines are ignored - } else if (line.startsWith("newmtl ")) { - addMaterial(name); - name = line.substring("newmtl ".length()); - } else if (line.startsWith("Kd ")) { - material.setDiffuseColor(readColor(line.substring(3))); - modified = true; - } else if (line.startsWith("Ks ")) { - material.setSpecularColor(readColor(line.substring(3))); - modified = true; - } else if (line.startsWith("Ns ")) { - material.setSpecularPower(Double.parseDouble(line.substring(3))); - modified = true; - } else if (line.startsWith("map_Kd ")) { - material.setDiffuseColor(Color.WHITE); - material.setDiffuseMap(loadImage(line.substring("map_Kd ".length()))); - // material.setSelfIlluminationMap(loadImage(line.substring("map_Kd ".length()))); - // material.setSpecularColor(Color.WHITE); - modified = true; - // } else if (line.startsWith("illum ")) { - // int illumNo = Integer.parseInt(line.substring("illum ".length())); - /* - 0 Color on and Ambient off - 1 Color on and Ambient on - 2 Highlight on - 3 Reflection on and Ray trace on - 4 Transparency: Glass on - Reflection: Ray trace on - 5 Reflection: Fresnel on and Ray trace on - 6 Transparency: Refraction on - Reflection: Fresnel off and Ray trace on - 7 Transparency: Refraction on - Reflection: Fresnel on and Ray trace on - 8 Reflection on and Ray trace off - 9 Transparency: Glass on - Reflection: Ray trace off - 10 Casts shadows onto invisible surfaces - */ - } else { - log("material line ignored for " + name + ": " + line); - } - } catch (Exception ex) { - Logger.getLogger(MtlReader.class.getName()) - .log(Level.SEVERE, "Failed to parse line:" + line, ex); - } - } - addMaterial(name); - } - - private Color readColor(String line) { - String[] split = line.trim() - .split(" +"); - float red = Float.parseFloat(split[0]); - float green = Float.parseFloat(split[1]); - float blue = Float.parseFloat(split[2]); - return Color.color(red, green, blue); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/ObjImporter.java b/gui/src/main/java/com/javafx/experiments/importers/obj/ObjImporter.java deleted file mode 100644 index 662cd5c..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/ObjImporter.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.javafx.experiments.importers.SmoothingGroups; - -import javafx.scene.paint.Color; -import javafx.scene.paint.Material; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.CullFace; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; - -/** Obj file reader */ -public class ObjImporter { - - private static boolean debug = false; - - private static boolean flatXZ = false; - - private static float scale = 1; - - public static void setDebug(boolean debug) { - ObjImporter.debug = debug; - } - - public static void setFlatXZ(boolean flatXZ) { - ObjImporter.flatXZ = flatXZ; - } - - public static void setScale(float scale) { - ObjImporter.scale = scale; - } - - static void log(String string) { - if (debug) { - System.out.println(string); - } - } - - private IntegerArrayList faceNormals = new IntegerArrayList(); - - private IntegerArrayList faces = new IntegerArrayList(); - private int facesNormalStart = 0; - private int facesStart = 0; - private Material material = new PhongMaterial(Color.WHITE); - - private List> materialLibrary = new ArrayList<>(); - - private Map materials = new HashMap<>(); - - private Map meshes = new HashMap<>(); - - private FloatArrayList normals = new FloatArrayList(); - - private String objFileUrl; - - private IntegerArrayList smoothingGroups = new IntegerArrayList(); - - private int smoothingGroupsStart = 0; - - private FloatArrayList uvs = new FloatArrayList(); - - private FloatArrayList vertexes = new FloatArrayList(); - - public ObjImporter(InputStream inputStream) throws IOException { - read(inputStream); - } - - public ObjImporter(String objFileUrl) throws FileNotFoundException, - IOException { - this.objFileUrl = objFileUrl; - log("Reading filename = " + objFileUrl); - read(new URL(objFileUrl).openStream()); - } - - public MeshView buildMeshView(String key) { - MeshView meshView = new MeshView(); - meshView.setId(key); - meshView.setMaterial(materials.get(key)); - meshView.setMesh(meshes.get(key)); - meshView.setCullFace(CullFace.NONE); - return meshView; - } - - public Material getMaterial() { - return materials.values() - .iterator() - .next(); - } - - public Material getMaterial(String key) { - return materials.get(key); - } - - public TriangleMesh getMesh() { - return meshes.values() - .iterator() - .next(); - } - - public TriangleMesh getMesh(String key) { - return meshes.get(key); - } - - public Set getMeshes() { - return meshes.keySet(); - } - - private void addMesh(String key) { - if (facesStart >= faces.size()) { - // we're only interested in faces - smoothingGroupsStart = smoothingGroups.size(); - return; - } - Map vertexMap = new HashMap<>(vertexes.size() / 2); - Map uvMap = new HashMap<>(uvs.size() / 2); - Map normalMap = new HashMap<>(normals.size() / 2); - FloatArrayList newVertexes = new FloatArrayList(vertexes.size() / 2); - FloatArrayList newUVs = new FloatArrayList(uvs.size() / 2); - FloatArrayList newNormals = new FloatArrayList(normals.size() / 2); - boolean useNormals = true; - - for (int i = facesStart; i < faces.size(); i += 2) { - int vi = faces.get(i); - Integer nvi = vertexMap.get(vi); - if (nvi == null) { - nvi = newVertexes.size() / 3; - vertexMap.put(vi, nvi); - newVertexes.add(vertexes.get(vi * 3)); - newVertexes.add(vertexes.get(vi * 3 + 1)); - newVertexes.add(vertexes.get(vi * 3 + 2)); - } - faces.set(i, nvi); - - int uvi = faces.get(i + 1); - Integer nuvi = uvMap.get(uvi); - if (nuvi == null) { - nuvi = newUVs.size() / 2; - uvMap.put(uvi, nuvi); - if (uvi >= 0) { - newUVs.add(uvs.get(uvi * 2)); - newUVs.add(uvs.get(uvi * 2 + 1)); - } else { - newUVs.add(0f); - newUVs.add(0f); - } - } - faces.set(i + 1, nuvi); - - if (useNormals) { - int ni = faceNormals.get(i / 2); - Integer nni = normalMap.get(ni); - if (nni == null) { - nni = newNormals.size() / 3; - normalMap.put(ni, nni); - if (ni >= 0 && normals.size() >= (ni + 1) * 3) { - newNormals.add(normals.get(ni * 3)); - newNormals.add(normals.get(ni * 3 + 1)); - newNormals.add(normals.get(ni * 3 + 2)); - } else { - useNormals = false; - newNormals.add(0f); - newNormals.add(0f); - newNormals.add(0f); - } - } - faceNormals.set(i / 2, nni); - } - } - - TriangleMesh mesh = new TriangleMesh(); - mesh.getPoints() - .setAll(newVertexes.toFloatArray()); - mesh.getTexCoords() - .setAll(newUVs.toFloatArray()); - mesh.getFaces() - .setAll(((IntegerArrayList) faces.subList(facesStart, - faces.size())).toIntArray()); - - // Use normals if they are provided - if (useNormals) { - int[] newFaces = ((IntegerArrayList) faces.subList(facesStart, - faces.size())).toIntArray(); - int[] newFaceNormals = ((IntegerArrayList) faceNormals.subList(facesNormalStart, - faceNormals.size())).toIntArray(); - int[] smGroups = SmoothingGroups.calcSmoothGroups(mesh, newFaces, - newFaceNormals, - newNormals.toFloatArray()); - mesh.getFaceSmoothingGroups() - .setAll(smGroups); - } else { - mesh.getFaceSmoothingGroups() - .setAll(((IntegerArrayList) smoothingGroups.subList(smoothingGroupsStart, - smoothingGroups.size())).toIntArray()); - } - - int keyIndex = 2; - String keyBase = key; - while (meshes.get(key) != null) { - key = keyBase + " (" + keyIndex++ + ")"; - } - meshes.put(key, mesh); - materials.put(key, material); - - log("Added mesh '" + key + "' of " + mesh.getPoints() - .size() - / mesh.getPointElementSize() - + " vertexes, " + mesh.getTexCoords() - .size() - / mesh.getTexCoordElementSize() - + " uvs, " + mesh.getFaces() - .size() - / mesh.getFaceElementSize() - + " faces, " + mesh.getFaceSmoothingGroups() - .size() - + " smoothing groups."); - log("material diffuse color = " - + ((PhongMaterial) material).getDiffuseColor()); - log("material diffuse map = " - + ((PhongMaterial) material).getDiffuseMap()); - - facesStart = faces.size(); - facesNormalStart = faceNormals.size(); - smoothingGroupsStart = smoothingGroups.size(); - } - - private int normalIndex(int normalIndex) { - if (normalIndex < 0) { - return normalIndex + normals.size() / 3; - } else { - return normalIndex - 1; - } - } - - private void read(InputStream inputStream) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); - String line; - int currentSmoothGroup = 0; - String key = "default"; - while ((line = br.readLine()) != null) { - try { - if (line.startsWith("g ") || line.equals("g")) { - addMesh(key); - key = line.length() > 2 ? line.substring(2) : "default"; - log("key = " + key); - } else if (line.startsWith("v ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - float x = Float.parseFloat(split[0]) * scale; - float y = Float.parseFloat(split[1]) * scale; - float z = Float.parseFloat(split[2]) * scale; - - // log("x = " + x + ", y = " + y + ", z = " + z); - - vertexes.add(x); - vertexes.add(y); - vertexes.add(z); - - if (flatXZ) { - uvs.add(x); - uvs.add(z); - } - } else if (line.startsWith("vt ")) { - String[] split = line.substring(3) - .trim() - .split(" +"); - float u = Float.parseFloat(split[0]); - float v = Float.parseFloat(split[1]); - - // log("u = " + u + ", v = " + v); - - uvs.add(u); - uvs.add(1 - v); - } else if (line.startsWith("f ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - int[][] data = new int[split.length][]; - boolean uvProvided = true; - boolean normalProvided = true; - for (int i = 0; i < split.length; i++) { - String[] split2 = split[i].split("/"); - if (split2.length < 2) { - uvProvided = false; - } - if (split2.length < 3) { - normalProvided = false; - } - data[i] = new int[split2.length]; - for (int j = 0; j < split2.length; j++) { - if (split2[j].length() == 0) { - data[i][j] = 0; - if (j == 1) { - uvProvided = false; - } - if (j == 2) { - normalProvided = false; - } - } else { - data[i][j] = Integer.parseInt(split2[j]); - } - } - } - int v1 = vertexIndex(data[0][0]); - int uv1 = -1; - int n1 = -1; - if (uvProvided && !flatXZ) { - uv1 = uvIndex(data[0][1]); - if (uv1 < 0) { - uvProvided = false; - } - } - if (normalProvided) { - n1 = normalIndex(data[0][2]); - if (n1 < 0) { - normalProvided = false; - } - } - for (int i = 1; i < data.length - 1; i++) { - int v2 = vertexIndex(data[i][0]); - int v3 = vertexIndex(data[i + 1][0]); - int uv2 = -1; - int uv3 = -1; - int n2 = -1; - int n3 = -1; - if (uvProvided && !flatXZ) { - uv2 = uvIndex(data[i][1]); - uv3 = uvIndex(data[i + 1][1]); - } - if (normalProvided) { - n2 = normalIndex(data[i][2]); - n3 = normalIndex(data[i + 1][2]); - } - - // log("v1 = " + v1 + ", v2 = " + v2 + ", v3 = " + v3); - // log("uv1 = " + uv1 + ", uv2 = " + uv2 + ", uv3 = " + uv3); - - faces.add(v1); - faces.add(uv1); - faces.add(v2); - faces.add(uv2); - faces.add(v3); - faces.add(uv3); - faceNormals.add(n1); - faceNormals.add(n2); - faceNormals.add(n3); - - smoothingGroups.add(currentSmoothGroup); - } - } else if (line.startsWith("s ")) { - if (line.substring(2) - .equals("off")) { - currentSmoothGroup = 0; - } else { - currentSmoothGroup = Integer.parseInt(line.substring(2)); - } - } else if (line.startsWith("mtllib ")) { - // setting materials lib - String[] split = line.substring("mtllib ".length()) - .trim() - .split(" +"); - for (String filename : split) { - MtlReader mtlReader = new MtlReader(filename, - objFileUrl); - materialLibrary.add(mtlReader.getMaterials()); - } - } else if (line.startsWith("usemtl ")) { - addMesh(key); - // setting new material for next mesh - String materialName = line.substring("usemtl ".length()); - for (Map mm : materialLibrary) { - Material m = mm.get(materialName); - if (m != null) { - material = m; - break; - } - } - } else if (line.isEmpty() || line.startsWith("#")) { - // comments and empty lines are ignored - } else if (line.startsWith("vn ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - float x = Float.parseFloat(split[0]); - float y = Float.parseFloat(split[1]); - float z = Float.parseFloat(split[2]); - normals.add(x); - normals.add(y); - normals.add(z); - } else { - log("line skipped: " + line); - } - } catch (Exception ex) { - Logger.getLogger(MtlReader.class.getName()) - .log(Level.SEVERE, "Failed to parse line:" + line, ex); - } - } - addMesh(key); - - log("Totally loaded " + (vertexes.size() / 3.) + " vertexes, " - + (uvs.size() / 2.) + " uvs, " + (faces.size() / 6.) + " faces, " - + smoothingGroups.size() + " smoothing groups."); - } - - private int uvIndex(int uvIndex) { - if (uvIndex < 0) { - return uvIndex + uvs.size() / 2; - } else { - return uvIndex - 1; - } - } - - private int vertexIndex(int vertexIndex) { - if (vertexIndex < 0) { - return vertexIndex + vertexes.size() / 3; - } else { - return vertexIndex - 1; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/ObjOrPolyObjImporter.java b/gui/src/main/java/com/javafx/experiments/importers/obj/ObjOrPolyObjImporter.java deleted file mode 100644 index 0b6b2e3..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/ObjOrPolyObjImporter.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import java.io.IOException; - -import com.javafx.experiments.importers.Importer; - -import javafx.scene.Group; - -/** - * object loader - */ -public class ObjOrPolyObjImporter extends Importer { - - final Group res = new Group(); - - @Override - public Group getRoot() { - return res; - } - - @Override - public boolean isSupported(String extension) { - return extension != null && extension.equals("obj"); - } - - @Override - public void load(String fileUrl, boolean asPolygonMesh) throws IOException { - - if (asPolygonMesh) { - PolyObjImporter reader = new PolyObjImporter(fileUrl); - for (String mesh : reader.getMeshes()) { - res.getChildren() - .add(reader.buildPolygonMeshView(mesh)); - } - ; - } else { - ObjImporter reader = new ObjImporter(fileUrl); - for (String mesh : reader.getMeshes()) { - res.getChildren() - .add(reader.buildMeshView(mesh)); - } - ; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/importers/obj/PolyObjImporter.java b/gui/src/main/java/com/javafx/experiments/importers/obj/PolyObjImporter.java deleted file mode 100644 index 0c252d9..0000000 --- a/gui/src/main/java/com/javafx/experiments/importers/obj/PolyObjImporter.java +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.importers.obj; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.javafx.experiments.importers.SmoothingGroups; -import com.javafx.experiments.shape3d.PolygonMesh; -import com.javafx.experiments.shape3d.PolygonMeshView; - -import javafx.scene.paint.Color; -import javafx.scene.paint.Material; -import javafx.scene.paint.PhongMaterial; - -/** - * OBJ object loader - */ -public class PolyObjImporter { - - private static boolean debug = false; - - private static boolean flatXZ = false; - - private static float scale = 1; - - public static void setDebug(boolean debug) { - PolyObjImporter.debug = debug; - } - - public static void setFlatXZ(boolean flatXZ) { - PolyObjImporter.flatXZ = flatXZ; - } - - public static void setScale(float scale) { - PolyObjImporter.scale = scale; - } - - static void log(String string) { - if (debug) { - System.out.println(string); - } - } - - private List faceNormals = new ArrayList<>(); - - private List faces = new ArrayList<>(); - private int facesNormalStart = 0; - private int facesStart = 0; - private Material material = new PhongMaterial(Color.WHITE); - - private List> materialLibrary = new ArrayList<>(); - - private Map materials = new HashMap<>(); - - private Map meshes = new HashMap<>(); - - private FloatArrayList normals = new FloatArrayList(); - - private String objFilename; - - private IntegerArrayList smoothingGroups = new IntegerArrayList(); - - private int smoothingGroupsStart = 0; - - private FloatArrayList uvs = new FloatArrayList(); - - private FloatArrayList vertexes = new FloatArrayList(); - - public PolyObjImporter(InputStream inputStream) throws IOException { - read(inputStream); - } - - public PolyObjImporter(String filename) throws FileNotFoundException, - IOException { - this.objFilename = filename; - log("Reading filename = " + filename); - ; - read(new URL(filename).openStream()); - } - - public PolygonMeshView buildPolygonMeshView(String key) { - PolygonMeshView polygonMeshView = new PolygonMeshView(); - polygonMeshView.setId(key); - polygonMeshView.setMaterial(materials.get(key)); - polygonMeshView.setMesh(meshes.get(key)); - // polygonMeshView.setCullFace(CullFace.NONE); TODO - return polygonMeshView; - } - - public Material getMaterial() { - return materials.values() - .iterator() - .next(); - } - - public Material getMaterial(String key) { - return materials.get(key); - } - - public PolygonMesh getMesh() { - return meshes.values() - .iterator() - .next(); - } - - public PolygonMesh getMesh(String key) { - return meshes.get(key); - } - - public Set getMeshes() { - return meshes.keySet(); - } - - private void addMesh(String key) { - if (facesStart >= faces.size()) { - // we're only interested in faces - smoothingGroupsStart = smoothingGroups.size(); - return; - } - Map vertexMap = new HashMap<>(vertexes.size() / 2); - Map uvMap = new HashMap<>(uvs.size() / 2); - Map normalMap = new HashMap<>(normals.size() / 2); - FloatArrayList newVertexes = new FloatArrayList(vertexes.size() / 2); - FloatArrayList newUVs = new FloatArrayList(uvs.size() / 2); - FloatArrayList newNormals = new FloatArrayList(normals.size() / 2); - boolean useNormals = true; - - int[][] faceArrays = new int[faces.size() - facesStart][]; - int[][] faceNormalArrays = new int[faceNormals.size() - - facesNormalStart][]; - - for (int i = facesStart; i < faces.size(); i++) { - int[] faceIndexes = faces.get(i); - int[] faceNormalIndexes = faceNormals.get(i); - for (int j = 0; j < faceIndexes.length; j += 2) { - int vi = faceIndexes[j]; - Integer nvi = vertexMap.get(vi); - if (nvi == null) { - nvi = newVertexes.size() / 3; - vertexMap.put(vi, nvi); - newVertexes.add(vertexes.get(vi * 3)); - newVertexes.add(vertexes.get(vi * 3 + 1)); - newVertexes.add(vertexes.get(vi * 3 + 2)); - } - faceIndexes[j] = nvi; - // faces.set(i, nvi); - int uvi = faceIndexes[j + 1]; - Integer nuvi = uvMap.get(uvi); - if (nuvi == null) { - nuvi = newUVs.size() / 2; - uvMap.put(uvi, nuvi); - if (uvi >= 0) { - newUVs.add(uvs.get(uvi * 2)); - newUVs.add(uvs.get(uvi * 2 + 1)); - } else { - newUVs.add(0f); - newUVs.add(0f); - } - } - faceIndexes[j + 1] = nuvi; - // faces.set(i + 1, nuvi); - - int ni = faceNormalIndexes[j / 2]; - Integer nni = normalMap.get(ni); - if (nni == null) { - nni = newNormals.size() / 3; - normalMap.put(ni, nni); - if (ni >= 0 && normals.size() >= (ni + 1) * 3) { - newNormals.add(normals.get(ni * 3)); - newNormals.add(normals.get(ni * 3 + 1)); - newNormals.add(normals.get(ni * 3 + 2)); - } else { - useNormals = false; - newNormals.add(0f); - newNormals.add(0f); - newNormals.add(0f); - } - } - faceNormalIndexes[j / 2] = nni; - } - faceArrays[i - facesStart] = faceIndexes; - faceNormalArrays[i - facesNormalStart] = faceNormalIndexes; - } - - PolygonMesh mesh = new PolygonMesh(newVertexes.toFloatArray(), - newUVs.toFloatArray(), faceArrays); - - // Use normals if they are provided - if (useNormals) { - int[] smGroups = SmoothingGroups.calcSmoothGroups(faceArrays, - faceNormalArrays, - newNormals.toFloatArray()); - mesh.getFaceSmoothingGroups() - .setAll(smGroups); - } else { - mesh.getFaceSmoothingGroups() - .setAll(((IntegerArrayList) smoothingGroups.subList(smoothingGroupsStart, - smoothingGroups.size())).toIntArray()); - } - - if (debug) { - System.out.println("mesh.points = " + mesh.getPoints()); - System.out.println("mesh.texCoords = " + mesh.getTexCoords()); - System.out.println("mesh.faces: "); - for (int[] face : mesh.faces) { - System.out.println(" face:: " + Arrays.toString(face)); - } - } - - int keyIndex = 2; - String keyBase = key; - while (meshes.get(key) != null) { - key = keyBase + " (" + keyIndex++ + ")"; - } - meshes.put(key, mesh); - materials.put(key, material); - - log("Added mesh '" + key + "' of " + (mesh.getPoints() - .size() - / 3) - + " vertexes, " + (mesh.getTexCoords() - .size() - / 2) - + " uvs, " + mesh.faces.length + " faces, " + 0 - + " smoothing groups."); - log("material diffuse color = " - + ((PhongMaterial) material).getDiffuseColor()); - log("material diffuse map = " - + ((PhongMaterial) material).getDiffuseMap()); - - facesStart = faces.size(); - facesNormalStart = faceNormals.size(); - smoothingGroupsStart = smoothingGroups.size(); - } - - private int normalIndex(int normalIndex) { - if (normalIndex < 0) { - return normalIndex + normals.size() / 3; - } else { - return normalIndex - 1; - } - } - - private void read(InputStream inputStream) throws IOException { - BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); - String line; - int currentSmoothGroup = 0; - String key = "default"; - while ((line = br.readLine()) != null) { - try { - if (line.startsWith("g ") || line.equals("g")) { - addMesh(key); - key = line.length() > 2 ? line.substring(2) : "default"; - log("key = " + key); - } else if (line.startsWith("v ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - float x = Float.parseFloat(split[0]) * scale; - float y = Float.parseFloat(split[1]) * scale; - float z = Float.parseFloat(split[2]) * scale; - - // log("x = " + x + ", y = " + y + ", z = " + z); - - vertexes.add(x); - vertexes.add(y); - vertexes.add(z); - - if (flatXZ) { - uvs.add(x); - uvs.add(z); - } - } else if (line.startsWith("vt ")) { - String[] split = line.substring(3) - .trim() - .split(" +"); - float u = split[0].trim() - .equalsIgnoreCase("nan") ? Float.NaN - : Float.parseFloat(split[0]); - float v = split[1].trim() - .equalsIgnoreCase("nan") ? Float.NaN - : Float.parseFloat(split[1]); - - // log("u = " + u + ", v = " + v); - - uvs.add(u); - uvs.add(1 - v); - } else if (line.startsWith("f ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - int[] faceIndexes = new int[split.length * 2]; - int[] faceNormalIndexes = new int[split.length]; - for (int i = 0; i < split.length; i++) { - String[] split2 = split[i].split("/"); - faceIndexes[i - * 2] = vertexIndex(Integer.parseInt(split2[0])); - faceIndexes[(i * 2) - + 1] = (split2.length > 1 - && split2[1].length() > 0) ? uvIndex(Integer.parseInt(split2[1])) - : -1; - faceNormalIndexes[i] = (split2.length > 2 - && split2[2].length() > 0) ? normalIndex(Integer.parseInt(split2[2])) - : -1; - } - faces.add(faceIndexes); - faceNormals.add(faceNormalIndexes); - smoothingGroups.add(currentSmoothGroup); - } else if (line.startsWith("s ")) { - if (line.substring(2) - .equals("off")) { - currentSmoothGroup = 0; - } else { - currentSmoothGroup = Integer.parseInt(line.substring(2)); - } - } else if (line.startsWith("mtllib ")) { - // setting materials lib - String[] split = line.substring("mtllib ".length()) - .trim() - .split(" +"); - for (String filename : split) { - MtlReader mtlReader = new MtlReader(filename, - objFilename); - materialLibrary.add(mtlReader.getMaterials()); - } - } else if (line.startsWith("usemtl ")) { - addMesh(key); - // setting new material for next mesh - String materialName = line.substring("usemtl ".length()); - for (Map mm : materialLibrary) { - Material m = mm.get(materialName); - if (m != null) { - material = m; - break; - } - } - } else if (line.isEmpty() || line.startsWith("#")) { - // comments and empty lines are ignored - } else if (line.startsWith("vn ")) { - String[] split = line.substring(2) - .trim() - .split(" +"); - float x = Float.parseFloat(split[0]); - float y = Float.parseFloat(split[1]); - float z = Float.parseFloat(split[2]); - normals.add(x); - normals.add(y); - normals.add(z); - } else { - log("line skipped: " + line); - } - } catch (Exception ex) { - Logger.getLogger(MtlReader.class.getName()) - .log(Level.SEVERE, "Failed to parse line:" + line, ex); - } - } - addMesh(key); - - log("Totally loaded " + (vertexes.size() / 3.) + " vertexes, " - + (uvs.size() / 2.) + " uvs, " + (faces.size() / 6.) + " faces, " - + smoothingGroups.size() + " smoothing groups."); - } - - private int uvIndex(int uvIndex) { - if (uvIndex < 0) { - return uvIndex + uvs.size() / 2; - } else { - return uvIndex - 1; - } - } - - private int vertexIndex(int vertexIndex) { - if (vertexIndex < 0) { - return vertexIndex + vertexes.size() / 3; - } else { - return vertexIndex - 1; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/AutoScalingGroup.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/AutoScalingGroup.java deleted file mode 100644 index 30c67ae..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/AutoScalingGroup.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.util.List; - -import javafx.beans.property.SimpleBooleanProperty; -import javafx.geometry.Bounds; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.transform.Scale; -import javafx.scene.transform.Translate; - -/** - * A Group that auto scales its self to fit its content in a given size box. - */ -public class AutoScalingGroup extends Group { - private boolean autoScale = false; - private SimpleBooleanProperty enabled = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - getTransforms().setAll(scale, - translate); - } else { - getTransforms().clear(); - } - } - }; - private Scale scale = new Scale(1, 1, 1, 0, 0, 0); - private Translate translate = new Translate(0, 0, 0); - private double twoSize; - - /** - * Create AutoScalingGroup - * - * @param size - * half of width/height/depth of box to fit content into - */ - public AutoScalingGroup(double size) { - this.twoSize = size * 2; - getTransforms().addAll(scale, translate); - } - - /** - * Get enabled property - * - * @return enabled property - */ - public SimpleBooleanProperty enabledProperty() { - return enabled; - } - - /** - * Get is auto scaling enabled - * - * @return true if auto scaling is enabled - */ - public boolean isEnabled() { - return enabled.get(); - } - - /** - * Set is auto scaling enabled - * - * @param enabled - * true if auto scaling is enabled - */ - public void setEnabled(boolean enabled) { - this.enabled.set(enabled); - } - - @Override - protected void layoutChildren() { - if (autoScale) { - List children = getChildren(); - double minX = Double.MAX_VALUE, minY = Double.MAX_VALUE, - minZ = Double.MAX_VALUE; - double maxX = Double.MIN_VALUE, maxY = Double.MIN_VALUE, - maxZ = Double.MIN_VALUE; - boolean first = true; - for (int i = 0, max = children.size(); i < max; i++) { - final Node node = children.get(i); - if (node.isVisible()) { - Bounds bounds = node.getBoundsInLocal(); - // if the bounds of the child are invalid, we don't want - // to use those in the remaining computations. - if (bounds.isEmpty()) { - continue; - } - if (first) { - minX = bounds.getMinX(); - minY = bounds.getMinY(); - minZ = bounds.getMinZ(); - maxX = bounds.getMaxX(); - maxY = bounds.getMaxY(); - maxZ = bounds.getMaxZ(); - first = false; - } else { - minX = Math.min(bounds.getMinX(), minX); - minY = Math.min(bounds.getMinY(), minY); - minZ = Math.min(bounds.getMinZ(), minZ); - maxX = Math.max(bounds.getMaxX(), maxX); - maxY = Math.max(bounds.getMaxY(), maxY); - maxZ = Math.max(bounds.getMaxZ(), maxZ); - } - } - } - - final double w = maxX - minX; - final double h = maxY - minY; - final double d = maxZ - minZ; - - final double centerX = minX + (w / 2); - final double centerY = minY + (h / 2); - double scaleX = twoSize / w; - double scaleY = twoSize / h; - double scaleZ = twoSize / d; - - double scale = Math.min(scaleX, Math.min(scaleY, scaleZ)); - this.scale.setX(scale); - this.scale.setY(scale); - this.scale.setZ(scale); - - this.translate.setX(-centerX); - this.translate.setY(-centerY); - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/ContentModel.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/ContentModel.java deleted file mode 100644 index 2a6a50e..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/ContentModel.java +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import com.javafx.experiments.shape3d.PolygonMeshView; -import com.javafx.experiments.shape3d.SubdivisionMesh; - -import javafx.animation.Timeline; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.event.EventHandler; -import javafx.scene.AmbientLight; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.PerspectiveCamera; -import javafx.scene.PointLight; -import javafx.scene.SubScene; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.MouseEvent; -import javafx.scene.input.ScrollEvent; -import javafx.scene.input.ZoomEvent; -import javafx.scene.layout.Region; -import javafx.scene.paint.Color; -import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.Box; -import javafx.scene.shape.DrawMode; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.Sphere; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Translate; -import javafx.util.Duration; - -/** - * 3D Content Model for Viewer App. Contains the 3D scene and everything related - * to it: light, cameras etc. - */ -public class ContentModel { - private AmbientLight ambientLight = new AmbientLight(Color.DARKGREY); - private SimpleBooleanProperty ambientLightEnabled = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - root3D.getChildren() - .add(ambientLight); - } else { - root3D.getChildren() - .remove(ambientLight); - } - } - }; - private AutoScalingGroup autoScalingGroup = new AutoScalingGroup(2); - private SubdivisionMesh.BoundaryMode boundaryMode = SubdivisionMesh.BoundaryMode.CREASE_EDGES; - private final PerspectiveCamera camera = new PerspectiveCamera(true); - private final double cameraDistance = 200; - private final Rotate cameraLookXRotate = new Rotate(0, - 0, - 0, - 0, - Rotate.X_AXIS); - private final Rotate cameraLookZRotate = new Rotate(0, - 0, - 0, - 0, - Rotate.Z_AXIS); - private final Translate cameraPosition = new Translate(0, - 0, - 0); - private final Xform cameraXform = new Xform(); - private final Xform cameraXform2 = new Xform(); - private final Xform cameraXform3 = new Xform(); - private final Rotate cameraXRotate = new Rotate(-20, - 0, - 0, - 0, - Rotate.X_AXIS); - private final Rotate cameraYRotate = new Rotate(-20, - 0, - 0, - 0, - Rotate.Y_AXIS); - private ObjectProperty content = new SimpleObjectProperty<>(); - @SuppressWarnings({ "unused" }) - private double dragStartX, dragStartY, - dragStartRotateX, dragStartRotateY; - private final EventHandler keyEventHandler = event -> { - /* - if (!Double.isNaN(event.getZoomFactor()) && event.getZoomFactor() > 0.8 && event.getZoomFactor() < 1.2) { - double z = cameraPosition.getZ()/event.getZoomFactor(); - z = Math.max(z,-1000); - z = Math.min(z,0); - cameraPosition.setZ(z); - } - */ - System.out.println("KeyEvent ..."); - Timeline timeline = getTimeline(); - Duration currentTime; - double CONTROL_MULTIPLIER = 0.1; - double SHIFT_MULTIPLIER = 0.1; - double ALT_MULTIPLIER = 0.5; - //System.out.println("--> handleKeyboard>handle"); - - // event.getEventType(); - - switch (event.getCode()) { - case F: - if (event.isControlDown()) { - //onButtonSave(); - } - break; - case O: - if (event.isControlDown()) { - //onButtonLoad(); - } - break; - case Z: - if (event.isShiftDown()) { - cameraXform.ry.setAngle(0.0); - cameraXform.rx.setAngle(0.0); - camera.setTranslateZ(-300.0); - } - cameraXform2.t.setX(0.0); - cameraXform2.t.setY(0.0); - break; - /* - case SPACE: - if (timelinePlaying) { - timeline.pause(); - timelinePlaying = false; - } - else { - timeline.play(); - timelinePlaying = true; - } - break; - */ - case UP: - if (event.isControlDown() - && event.isShiftDown()) { - cameraXform2.t.setY(cameraXform2.t.getY() - - 10.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown() - && event.isShiftDown()) { - cameraXform.rx.setAngle(cameraXform.rx.getAngle() - - 10.0 - * ALT_MULTIPLIER); - } else if (event.isControlDown()) { - cameraXform2.t.setY(cameraXform2.t.getY() - - 1.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown()) { - cameraXform.rx.setAngle(cameraXform.rx.getAngle() - - 2.0 - * ALT_MULTIPLIER); - } else if (event.isShiftDown()) { - double z = camera.getTranslateZ(); - double newZ = z - + 5.0 - * SHIFT_MULTIPLIER; - camera.setTranslateZ(newZ); - } - break; - case DOWN: - if (event.isControlDown() - && event.isShiftDown()) { - cameraXform2.t.setY(cameraXform2.t.getY() - + 10.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown() - && event.isShiftDown()) { - cameraXform.rx.setAngle(cameraXform.rx.getAngle() - + 10.0 - * ALT_MULTIPLIER); - } else if (event.isControlDown()) { - cameraXform2.t.setY(cameraXform2.t.getY() - + 1.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown()) { - cameraXform.rx.setAngle(cameraXform.rx.getAngle() - + 2.0 - * ALT_MULTIPLIER); - } else if (event.isShiftDown()) { - double z = camera.getTranslateZ(); - double newZ = z - - 5.0 - * SHIFT_MULTIPLIER; - camera.setTranslateZ(newZ); - } - break; - case RIGHT: - if (event.isControlDown() - && event.isShiftDown()) { - cameraXform2.t.setX(cameraXform2.t.getX() - + 10.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown() - && event.isShiftDown()) { - cameraXform.ry.setAngle(cameraXform.ry.getAngle() - - 10.0 - * ALT_MULTIPLIER); - } else if (event.isControlDown()) { - cameraXform2.t.setX(cameraXform2.t.getX() - + 1.0 - * CONTROL_MULTIPLIER); - } else if (event.isShiftDown()) { - currentTime = timeline.getCurrentTime(); - timeline.jumpTo(Frame.frame(Math.round(Frame.toFrame(currentTime) - / 10.0) - * 10 - + 10)); - // timeline.jumpTo(Duration.seconds(currentTime.toSeconds() + ONE_FRAME)); - } else if (event.isAltDown()) { - cameraXform.ry.setAngle(cameraXform.ry.getAngle() - - 2.0 - * ALT_MULTIPLIER); - } else { - currentTime = timeline.getCurrentTime(); - timeline.jumpTo(Frame.frame(Frame.toFrame(currentTime) - + 1)); - // timeline.jumpTo(Duration.seconds(currentTime.toSeconds() + ONE_FRAME)); - } - break; - case LEFT: - if (event.isControlDown() - && event.isShiftDown()) { - cameraXform2.t.setX(cameraXform2.t.getX() - - 10.0 - * CONTROL_MULTIPLIER); - } else if (event.isAltDown() - && event.isShiftDown()) { - cameraXform.ry.setAngle(cameraXform.ry.getAngle() - + 10.0 - * ALT_MULTIPLIER); // - - } else if (event.isControlDown()) { - cameraXform2.t.setX(cameraXform2.t.getX() - - 1.0 - * CONTROL_MULTIPLIER); - } else if (event.isShiftDown()) { - currentTime = timeline.getCurrentTime(); - timeline.jumpTo(Frame.frame(Math.round(Frame.toFrame(currentTime) - / 10.0) - * 10 - - 10)); - // timeline.jumpTo(Duration.seconds(currentTime.toSeconds() - ONE_FRAME)); - } else if (event.isAltDown()) { - cameraXform.ry.setAngle(cameraXform.ry.getAngle() - + 2.0 - * ALT_MULTIPLIER); // - - } else { - currentTime = timeline.getCurrentTime(); - timeline.jumpTo(Frame.frame(Frame.toFrame(currentTime) - - 1)); - // timeline.jumpTo(Duration.seconds(currentTime.toSeconds() - ONE_FRAME)); - } - break; - default: - break; - } - //System.out.println(cameraXform.getTranslateX() + ", " + cameraXform.getTranslateY() + ", " + cameraXform.getTranslateZ()); - - }; - private PointLight light1 = new PointLight(Color.WHITE); - private SimpleBooleanProperty light1Enabled = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - root3D.getChildren() - .add(light1); - } else { - root3D.getChildren() - .remove(light1); - } - } - }; - private PointLight light2 = new PointLight(Color.ANTIQUEWHITE); - private SimpleBooleanProperty light2Enabled = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - root3D.getChildren() - .add(light2); - } else { - root3D.getChildren() - .remove(light2); - } - } - }; - private PointLight light3 = new PointLight(Color.ALICEBLUE); - - private SimpleBooleanProperty light3Enabled = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - root3D.getChildren() - .add(light3); - } else { - root3D.getChildren() - .remove(light3); - } - } - }; - - private SubdivisionMesh.MapBorderMode mapBorderMode = SubdivisionMesh.MapBorderMode.NOT_SMOOTH; - - private double mouseDeltaX; - - private double mouseDeltaY; - private final EventHandler mouseEventHandler; - private double mouseOldX; - private double mouseOldY; - private double mousePosX; - private double mousePosY; - private SimpleBooleanProperty msaa = new SimpleBooleanProperty() { - @Override - protected void invalidated() { - rebuildSubScene(); - } - }; - private final Group root3D = new Group(); - private final EventHandler scrollEventHandler = event -> { - if (event.getTouchCount() > 0) { // touch pad scroll - cameraXform2.t.setX(cameraXform2.t.getX() - - (0.01 - * event.getDeltaX())); // - - cameraXform2.t.setY(cameraXform2.t.getY() - + (0.01 - * event.getDeltaY())); // - - } else { - double z = cameraPosition.getZ() - - (event.getDeltaY() - * 0.2); - z = Math.max(z, - -1000); - z = Math.min(z, - 0); - cameraPosition.setZ(z); - } - }; - private SimpleBooleanProperty showAxis = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - if (xAxis == null) { - createAxes(); - } - autoScalingGroup.getChildren() - .addAll(xAxis, - yAxis, - zAxis); - autoScalingGroup.getChildren() - .addAll(xSphere, - ySphere, - zSphere); - //root3D.getChildren().addAll(xAxis, yAxis, zAxis); - //root3D.getChildren().addAll(xSphere, ySphere, zSphere); - } else if (xAxis != null) { - autoScalingGroup.getChildren() - .removeAll(xAxis, - yAxis, - zAxis); - autoScalingGroup.getChildren() - .removeAll(xSphere, - ySphere, - zSphere); - //root3D.getChildren().removeAll(xAxis, yAxis, zAxis); - //root3D.getChildren().removeAll(xSphere, ySphere, zSphere); - } - } - }; - private int subdivisionLevel = 0; - private final SimpleObjectProperty subScene = new SimpleObjectProperty<>(); - - private final SimpleObjectProperty timeline = new SimpleObjectProperty<>(); - private boolean wireframe = false; - private Box xAxis, yAxis, zAxis; - private Sphere xSphere, ySphere, zSphere; - private SimpleBooleanProperty yUp = new SimpleBooleanProperty(false) { - @Override - protected void invalidated() { - if (get()) { - yUpRotate.setAngle(180); - //cameraPosition.setZ(cameraDistance); - // camera.setTranslateZ(cameraDistance); - } else { - yUpRotate.setAngle(0); - //cameraPosition.setZ(-cameraDistance); - // camera.setTranslateZ(-cameraDistance); - } - } - }; - private Rotate yUpRotate = new Rotate(0, - 0, - 0, - 0, - Rotate.X_AXIS); - - private final EventHandler zoomEventHandler = event -> { - if (!Double.isNaN(event.getZoomFactor()) - && event.getZoomFactor() > 0.8 - && event.getZoomFactor() < 1.2) { - double z = cameraPosition.getZ() - / event.getZoomFactor(); - z = Math.max(z, - -1000); - z = Math.min(z, - 0); - cameraPosition.setZ(z); - } - }; - { - contentProperty().addListener((ov, oldContent, newContent) -> { - autoScalingGroup.getChildren() - .remove(oldContent); - autoScalingGroup.getChildren() - .add(newContent); - setWireFrame(newContent, wireframe); - // TODO mesh is updated each time these are called even if no rendering needs to happen - setSubdivisionLevel(newContent, subdivisionLevel); - setBoundaryMode(newContent, boundaryMode); - setMapBorderMode(newContent, mapBorderMode); - }); - } - { - mouseEventHandler = event -> { - // System.out.println("MouseEvent ..."); - - double yFlip = 1.0; - if (getYUp()) { - yFlip = 1.0; - } else { - yFlip = -1.0; - } - if (event.getEventType() == MouseEvent.MOUSE_PRESSED) { - dragStartX = event.getSceneX(); - dragStartY = event.getSceneY(); - dragStartRotateX = cameraXRotate.getAngle(); - dragStartRotateY = cameraYRotate.getAngle(); - mousePosX = event.getSceneX(); - mousePosY = event.getSceneY(); - mouseOldX = event.getSceneX(); - mouseOldY = event.getSceneY(); - - } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) { - - double modifier = 1.0; - double modifierFactor = 0.3; - - if (event.isControlDown()) { - modifier = 0.1; - } - if (event.isShiftDown()) { - modifier = 10.0; - } - - mouseOldX = mousePosX; - mouseOldY = mousePosY; - mousePosX = event.getSceneX(); - mousePosY = event.getSceneY(); - mouseDeltaX = (mousePosX - mouseOldX); //*DELTA_MULTIPLIER; - mouseDeltaY = (mousePosY - mouseOldY); //*DELTA_MULTIPLIER; - - double flip = -1.0; - - @SuppressWarnings("unused") - boolean alt = (true || event.isAltDown()); // For now, don't require ALT to be pressed - if (alt && (event.isMiddleButtonDown() - || (event.isPrimaryButtonDown() - && event.isSecondaryButtonDown()))) { - cameraXform2.t.setX(cameraXform2.t.getX() - + flip * mouseDeltaX * modifierFactor - * modifier * 0.3); // - - cameraXform2.t.setY(cameraXform2.t.getY() - + yFlip * mouseDeltaY * modifierFactor - * modifier * 0.3); // - - } else if (alt && event.isPrimaryButtonDown()) { - cameraXform.ry.setAngle(cameraXform.ry.getAngle() - - yFlip * mouseDeltaX - * modifierFactor * modifier - * 2.0); // + - cameraXform.rx.setAngle(cameraXform.rx.getAngle() - + flip * mouseDeltaY - * modifierFactor * modifier - * 2.0); // - - } else if (alt && event.isSecondaryButtonDown()) { - double z = cameraPosition.getZ(); - // double z = camera.getTranslateZ(); - // double newZ = z + yFlip*flip*mouseDeltaX*modifierFactor*modifier; - double newZ = z - flip * (mouseDeltaX + mouseDeltaY) - * modifierFactor * modifier; - cameraPosition.setZ(newZ); - // camera.setTranslateZ(newZ); - } - - } - }; - } - - public ContentModel() { - // CAMERA - camera.setNearClip(1.0); // TODO: Workaround as per RT-31255 - camera.setFarClip(10000.0); // TODO: Workaround as per RT-31255 - - camera.getTransforms() - .addAll(yUpRotate, - //cameraXRotate, - //cameraYRotate, - cameraPosition, cameraLookXRotate, cameraLookZRotate); - //root3D.getChildren().add(camera); - root3D.getChildren() - .add(cameraXform); - cameraXform.getChildren() - .add(cameraXform2); - cameraXform2.getChildren() - .add(cameraXform3); - cameraXform3.getChildren() - .add(camera); - cameraPosition.setZ(-cameraDistance); - // camera.setTranslateZ(-cameraDistance); - root3D.getChildren() - .add(autoScalingGroup); - - SessionManager sessionManager = SessionManager.getSessionManager(); - sessionManager.bind(cameraLookXRotate.angleProperty(), - "cameraLookXRotate"); - sessionManager.bind(cameraLookZRotate.angleProperty(), - "cameraLookZRotate"); - sessionManager.bind(cameraPosition.xProperty(), "cameraPosition.x"); - sessionManager.bind(cameraPosition.yProperty(), "cameraPosition.y"); - sessionManager.bind(cameraPosition.zProperty(), "cameraPosition.z"); - sessionManager.bind(cameraXRotate.angleProperty(), "cameraXRotate"); - sessionManager.bind(cameraYRotate.angleProperty(), "cameraYRotate"); - sessionManager.bind(camera.nearClipProperty(), "cameraNearClip"); - sessionManager.bind(camera.farClipProperty(), "cameraFarClip"); - - // Build SubScene - rebuildSubScene(); - } - - public SimpleBooleanProperty ambientLightEnabledProperty() { - return ambientLightEnabled; - } - - public ObjectProperty contentProperty() { - return content; - } - - public AmbientLight getAmbientLight() { - return ambientLight; - } - - public boolean getAmbientLightEnabled() { - return ambientLightEnabled.get(); - } - - public AutoScalingGroup getAutoScalingGroup() { - return autoScalingGroup; - } - - public SubdivisionMesh.BoundaryMode getBoundaryMode() { - return boundaryMode; - } - - public PerspectiveCamera getCamera() { - return camera; - } - - public Rotate getCameraLookXRotate() { - return cameraLookXRotate; - } - - public Rotate getCameraLookZRotate() { - return cameraLookZRotate; - } - - public Translate getCameraPosition() { - return cameraPosition; - } - - public Rotate getCameraXRotate() { - return cameraXRotate; - } - - public Rotate getCameraYRotate() { - return cameraYRotate; - } - - public Node getContent() { - return content.get(); - } - - public PointLight getLight1() { - return light1; - } - - public boolean getLight1Enabled() { - return light1Enabled.get(); - } - - public PointLight getLight2() { - return light2; - } - - public boolean getLight2Enabled() { - return light2Enabled.get(); - } - - public PointLight getLight3() { - return light3; - } - - public boolean getLight3Enabled() { - return light3Enabled.get(); - } - - public SubdivisionMesh.MapBorderMode getMapBorderMode() { - return mapBorderMode; - } - - public boolean getMsaa() { - return msaa.get(); - } - - public Group getRoot3D() { - return root3D; - } - - public boolean getShowAxis() { - return showAxis.get(); - } - - public int getSubdivisionLevel() { - return subdivisionLevel; - } - - public SubScene getSubScene() { - return subScene.get(); - } - - public Timeline getTimeline() { - return timeline.get(); - } - - public boolean getYUp() { - return yUp.get(); - } - - public boolean isWireframe() { - return wireframe; - } - - public SimpleBooleanProperty light1EnabledProperty() { - return light1Enabled; - } - - public SimpleBooleanProperty light2EnabledProperty() { - return light2Enabled; - } - - public SimpleBooleanProperty light3EnabledProperty() { - return light3Enabled; - } - - public SimpleBooleanProperty msaaProperty() { - return msaa; - } - - public void setAmbientLightEnabled(boolean ambientLightEnabled) { - this.ambientLightEnabled.set(ambientLightEnabled); - } - - public void setBoundaryMode(SubdivisionMesh.BoundaryMode boundaryMode) { - this.boundaryMode = boundaryMode; - setBoundaryMode(root3D, boundaryMode); - } - - public void setContent(Node content) { - this.content.set(content); - } - - public void setLight1Enabled(boolean light1Enabled) { - this.light1Enabled.set(light1Enabled); - } - - public void setLight2Enabled(boolean light2Enabled) { - this.light2Enabled.set(light2Enabled); - } - - public void setLight3Enabled(boolean light3Enabled) { - this.light3Enabled.set(light3Enabled); - } - - public void setMapBorderMode(SubdivisionMesh.MapBorderMode mapBorderMode) { - this.mapBorderMode = mapBorderMode; - setMapBorderMode(root3D, mapBorderMode); - } - - public void setMsaa(boolean msaa) { - this.msaa.set(msaa); - } - - public void setShowAxis(boolean showAxis) { - this.showAxis.set(showAxis); - } - - public void setSubdivisionLevel(int subdivisionLevel) { - this.subdivisionLevel = subdivisionLevel; - setSubdivisionLevel(root3D, subdivisionLevel); - } - - public void setTimeline(Timeline timeline) { - this.timeline.set(timeline); - } - - public void setWireFrame(boolean wireframe) { - this.wireframe = wireframe; - setWireFrame(root3D, wireframe); - } - - public void setYUp(boolean yUp) { - this.yUp.set(yUp); - } - - public SimpleBooleanProperty showAxisProperty() { - return showAxis; - } - - public SimpleObjectProperty subSceneProperty() { - return subScene; - } - - public SimpleObjectProperty timelineProperty() { - return timeline; - } - - public SimpleBooleanProperty yUpProperty() { - return yUp; - } - - private void createAxes() { - double length = 200.0; - double width = 1.0; - double radius = 2.0; - final PhongMaterial redMaterial = new PhongMaterial(); - redMaterial.setDiffuseColor(Color.DARKRED); - redMaterial.setSpecularColor(Color.RED); - final PhongMaterial greenMaterial = new PhongMaterial(); - greenMaterial.setDiffuseColor(Color.DARKGREEN); - greenMaterial.setSpecularColor(Color.GREEN); - final PhongMaterial blueMaterial = new PhongMaterial(); - blueMaterial.setDiffuseColor(Color.DARKBLUE); - blueMaterial.setSpecularColor(Color.BLUE); - - xSphere = new Sphere(radius); - ySphere = new Sphere(radius); - zSphere = new Sphere(radius); - xSphere.setMaterial(redMaterial); - ySphere.setMaterial(greenMaterial); - zSphere.setMaterial(blueMaterial); - - xSphere.setTranslateX(100.0); - ySphere.setTranslateY(100.0); - zSphere.setTranslateZ(100.0); - - xAxis = new Box(length, width, width); - yAxis = new Box(width, length, width); - zAxis = new Box(width, width, length); - xAxis.setMaterial(redMaterial); - yAxis.setMaterial(greenMaterial); - zAxis.setMaterial(blueMaterial); - } - - private void rebuildSubScene() { - SubScene oldSubScene = this.subScene.get(); - if (oldSubScene != null) { - oldSubScene.setRoot(new Region()); - oldSubScene.setCamera(null); - oldSubScene.removeEventHandler(MouseEvent.ANY, mouseEventHandler); - oldSubScene.removeEventHandler(KeyEvent.ANY, keyEventHandler); - oldSubScene.removeEventHandler(ScrollEvent.ANY, scrollEventHandler); - } - - javafx.scene.SceneAntialiasing aaVal = msaa.get() ? javafx.scene.SceneAntialiasing.BALANCED - : javafx.scene.SceneAntialiasing.DISABLED; - SubScene subScene = new SubScene(root3D, 400, 400, true, aaVal); - this.subScene.set(subScene); - subScene.setFill(Color.ALICEBLUE); - subScene.setCamera(camera); - // SCENE EVENT HANDLING FOR CAMERA NAV - subScene.addEventHandler(MouseEvent.ANY, mouseEventHandler); - subScene.addEventHandler(KeyEvent.ANY, keyEventHandler); - // subScene.addEventFilter(KeyEvent.ANY, keyEventHandler); - subScene.addEventHandler(ZoomEvent.ANY, zoomEventHandler); - subScene.addEventHandler(ScrollEvent.ANY, scrollEventHandler); - - // Scene scene = subScene.getScene(); - // scene.addEventFilter(KeyEvent.ANY, keyEventHandler); - - /* - subScene.sceneProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue ov, Object t, Object t1) { - System.out.println("hello world"); - } - }); - */ - } - - private void setBoundaryMode(Node node, - SubdivisionMesh.BoundaryMode boundaryMode) { - if (node instanceof PolygonMeshView) { - ((PolygonMeshView) node).setBoundaryMode(boundaryMode); - } else if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - setBoundaryMode(child, boundaryMode); - } - } - } - - private void setMapBorderMode(Node node, - SubdivisionMesh.MapBorderMode mapBorderMode) { - if (node instanceof PolygonMeshView) { - ((PolygonMeshView) node).setMapBorderMode(mapBorderMode); - } else if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - setMapBorderMode(child, mapBorderMode); - } - } - } - - private void setSubdivisionLevel(Node node, int subdivisionLevel) { - if (node instanceof PolygonMeshView) { - ((PolygonMeshView) node).setSubdivisionLevel(subdivisionLevel); - } else if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - setSubdivisionLevel(child, subdivisionLevel); - } - } - } - - private void setWireFrame(Node node, boolean wireframe) { - if (node instanceof PolygonMeshView) { - ((PolygonMeshView) node).setDrawMode(wireframe ? DrawMode.LINE - : DrawMode.FILL); - } else if (node instanceof MeshView) { - ((MeshView) node).setDrawMode(wireframe ? DrawMode.LINE - : DrawMode.FILL); - } else if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - setWireFrame(child, wireframe); - } - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/FourWayNavControl.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/FourWayNavControl.java deleted file mode 100644 index 2364a15..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/FourWayNavControl.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.Timeline; -import javafx.event.EventHandler; -import javafx.geometry.Side; -import javafx.scene.input.MouseEvent; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Region; -import javafx.util.Duration; - -/** - * A four way control with 4 direction arrow buttons. - */ -public class FourWayNavControl extends GridPane { - - public static interface FourWayListener { - public void navigateStep(Side direction, double amount); - } - - private Side currentDirection = null; - private Timeline eventFiringTimeline; - private boolean hasFired = false; - - private FourWayListener listener; - - public FourWayNavControl() { - getStyleClass().addAll("button", "four-way"); - Region upIcon = new Region(); - upIcon.getStyleClass() - .add("up"); - Region downIcon = new Region(); - downIcon.getStyleClass() - .add("down"); - Region leftIcon = new Region(); - leftIcon.getStyleClass() - .add("left"); - Region rightIcon = new Region(); - rightIcon.getStyleClass() - .add("right"); - Region centerIcon = new Region(); - centerIcon.getStyleClass() - .add("center"); - - GridPane.setConstraints(upIcon, 1, 0); - GridPane.setConstraints(leftIcon, 0, 1); - GridPane.setConstraints(centerIcon, 1, 1); - GridPane.setConstraints(rightIcon, 2, 1); - GridPane.setConstraints(downIcon, 1, 2); - - getChildren().addAll(upIcon, downIcon, leftIcon, rightIcon, centerIcon); - - eventFiringTimeline = new Timeline(new KeyFrame(Duration.millis(80), - event -> { - if (listener != null - && currentDirection != null) { - listener.navigateStep(currentDirection, - 0.5); - } - hasFired = true; - })); - eventFiringTimeline.setDelay(Duration.millis(300)); - eventFiringTimeline.setCycleCount(Animation.INDEFINITE); - - upIcon.setOnMousePressed(event -> { - currentDirection = Side.TOP; - hasFired = false; - eventFiringTimeline.playFromStart(); - }); - downIcon.setOnMousePressed(event -> { - currentDirection = Side.BOTTOM; - hasFired = false; - eventFiringTimeline.playFromStart(); - }); - leftIcon.setOnMousePressed(event -> { - currentDirection = Side.LEFT; - hasFired = false; - eventFiringTimeline.playFromStart(); - }); - rightIcon.setOnMousePressed(event -> { - currentDirection = Side.RIGHT; - hasFired = false; - eventFiringTimeline.playFromStart(); - }); - - EventHandler stopHandler = event -> { - if (listener != null && currentDirection != null && !hasFired) { - listener.navigateStep(currentDirection, 10); - } - currentDirection = null; - eventFiringTimeline.stop(); - }; - upIcon.setOnMouseReleased(stopHandler); - downIcon.setOnMouseReleased(stopHandler); - rightIcon.setOnMouseReleased(stopHandler); - leftIcon.setOnMouseReleased(stopHandler); - } - - public FourWayListener getListener() { - return listener; - } - - public void setListener(FourWayListener listener) { - this.listener = listener; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Frame.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Frame.java deleted file mode 100644 index 7a44e02..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Frame.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.util.Duration; - -public class Frame extends Duration { - - // Experimentally trying to land the frames on whole frame values - // Duration is still double, but internally, in Animation/Timeline, - // the time is discrete. 6000 units per second. - // Without this EPSILON, the frames might not land on whole frame values. - // 0.000001f seems to work for now - // 0.0000001f was too small on a trial run - static double EPSILON = 0.000001; - - static double FPS = 24.0; - - private static final long serialVersionUID = 1L; - - // static double EPSILON = 0.0; - - public static Duration frame(int frame) { - return Duration.seconds(frame / FPS + EPSILON); - } - - public static Duration frame(long frame) { - return Duration.seconds(frame / FPS + EPSILON); - } - - public static long toFrame(Duration tion) { - return Math.round(tion.toSeconds() * FPS); - } - - public static double toFrameAsDouble(Duration tion) { - return (tion.toSeconds() * FPS); - } - - public static int toFrameAsInt(Duration tion) { - return (int) Math.round(tion.toSeconds() * FPS); - } - - Frame(double millis) { - super(millis); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Jfx3dViewerApp.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Jfx3dViewerApp.java deleted file mode 100644 index 2b4170a..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/Jfx3dViewerApp.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.io.File; -import java.util.List; - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.stage.Stage; - -/** - * JavaFX 3D Viewer Application - */ -public class Jfx3dViewerApp extends Application { - public static final String FILE_URL_PROPERTY = "fileUrl"; - private static ContentModel contentModel; - - public static ContentModel getContentModel() { - return contentModel; - } - - public static void main(String[] args) { - launch(args); - } - - private SessionManager sessionManager; - - @Override - public void start(Stage stage) throws Exception { - sessionManager = SessionManager.createSessionManager("Jfx3dViewerApp"); - sessionManager.loadSession(); - contentModel = new ContentModel(); - initializeContentModel(); - - List args = getParameters().getRaw(); - if (!args.isEmpty()) { - sessionManager.getProperties() - .setProperty(FILE_URL_PROPERTY, - new File(args.get(0)).toURI() - .toURL() - .toString()); - } - Scene scene = new Scene(FXMLLoader. load(Jfx3dViewerApp.class.getResource("main.fxml")), - 1024, 600); - stage.setScene(scene); - stage.show(); - - stage.setOnCloseRequest(event -> sessionManager.saveSession()); - - // org.scenicview.ScenicView.show(contentModel.getSubScene().getRoot()); - } - - protected void initializeContentModel() { - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/MainController.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/MainController.java deleted file mode 100644 index daa34d4..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/MainController.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.net.URLDecoder; -import java.util.ResourceBundle; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.javafx.experiments.exporters.fxml.FXMLExporter; -import com.javafx.experiments.exporters.javasource.JavaSourceExporter; -import com.javafx.experiments.importers.Importer3D; -import com.javafx.experiments.importers.Optimizer; - -import javafx.animation.Animation; -import javafx.animation.Interpolator; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.event.ActionEvent; -import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; -import javafx.geometry.BoundingBox; -import javafx.geometry.Bounds; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.control.Accordion; -import javafx.scene.control.Button; -import javafx.scene.control.CheckMenuItem; -import javafx.scene.control.Label; -import javafx.scene.control.SplitMenuButton; -import javafx.scene.control.SplitPane; -import javafx.scene.control.ToggleButton; -import javafx.scene.input.Dragboard; -import javafx.scene.input.TransferMode; -import javafx.scene.layout.Region; -import javafx.scene.shape.Box; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; -import javafx.stage.FileChooser; -import javafx.util.Duration; -import javafx.util.Pair; - -/** - * Controller class for main fxml file. - */ -public class MainController implements Initializable { - public Button endBtn; - public Button ffBtn; - public CheckMenuItem loadAsPolygonsCheckBox; - public ToggleButton loopBtn; - public SplitMenuButton openMenuBtn; - public CheckMenuItem optimizeCheckBox; - public ToggleButton playBtn; - public Button rwBtn; - public ToggleButton settingsBtn; - public SplitPane splitPane; - public Button startBtn; - public Label status; - public TimelineDisplay timelineDisplay; - private final ContentModel contentModel = Jfx3dViewerApp.getContentModel(); - private File loadedPath; - private String loadedURL; - private int meshCount = 0; - private int nodeCount = 0; - private SessionManager sessionManager = SessionManager.getSessionManager(); - private double settingsLastWidth = -1; - private Accordion settingsPanel; - private String[] supportedFormatRegex; - private TimelineController timelineController; - private int triangleCount = 0; - - public void export(ActionEvent event) { - FileChooser chooser = new FileChooser(); - if (loadedPath != null) { - chooser.setInitialDirectory(loadedPath.getAbsoluteFile() - .getParentFile()); - } - chooser.getExtensionFilters() - .addAll(new FileChooser.ExtensionFilter("FXML", "*.fxml"), - new FileChooser.ExtensionFilter("Java Source", - "*.java")); - chooser.setTitle("Export 3D Model"); - File newFile = chooser.showSaveDialog(openMenuBtn.getScene() - .getWindow()); - if (newFile != null) { - String extension = newFile.getName() - .substring(newFile.getName() - .lastIndexOf('.') - + 1, - newFile.getName() - .length()) - .toLowerCase(); - // System.out.println("extension = " + extension); - if ("java".equals(extension)) { - final String url = loadedURL; - // System.out.println("url = " + loadedPath); - final String baseUrl = url.substring(0, url.lastIndexOf('/')); - - JavaSourceExporter javaSourceExporter = new JavaSourceExporter(baseUrl, - contentModel.getContent(), - contentModel.getTimeline(), - newFile); - javaSourceExporter.export(); - } else if ("fxml".equals(extension)) { - new FXMLExporter(newFile.getAbsolutePath()).export(contentModel.getContent()); - } else { - System.err.println("Can not export a file of type [." - + extension + "]"); - } - } - } - - @SuppressWarnings("deprecation") - @Override - public void initialize(URL location, ResourceBundle resources) { - try { - // CREATE NAVIGATOR CONTROLS - Parent navigationPanel = FXMLLoader.load(MainController.class.getResource("navigation.fxml")); - // CREATE SETTINGS PANEL - settingsPanel = FXMLLoader.load(MainController.class.getResource("settings.fxml")); - // SETUP SPLIT PANE - splitPane.getItems() - .addAll(new SubSceneResizer(contentModel.subSceneProperty(), - navigationPanel), - settingsPanel); - splitPane.getDividers() - .get(0) - .setPosition(1); - } catch (IOException e) { - e.printStackTrace(); - } - // create timelineController; - timelineController = new TimelineController(startBtn, rwBtn, playBtn, - ffBtn, endBtn, loopBtn); - timelineController.timelineProperty() - .bind(contentModel.timelineProperty()); - timelineDisplay.timelineProperty() - .bind(contentModel.timelineProperty()); - // listen for drops - supportedFormatRegex = Importer3D.getSupportedFormatExtensionFilters(); - for (int i = 0; i < supportedFormatRegex.length; i++) { - supportedFormatRegex[i] = "." - + supportedFormatRegex[i].replaceAll("\\.", - "\\."); - // System.out.println("supportedFormatRegex[i] = " + supportedFormatRegex[i]); - } - contentModel.getSubScene() - .setOnDragOver(event -> { - Dragboard db = event.getDragboard(); - if (db.hasFiles()) { - boolean hasSupportedFile = false; - fileLoop: for (File file : db.getFiles()) { - for (String format : supportedFormatRegex) { - if (file.getName() - .matches(format)) { - hasSupportedFile = true; - break fileLoop; - } - } - } - if (hasSupportedFile) { - event.acceptTransferModes(TransferMode.COPY_OR_MOVE); - } - } - event.consume(); - }); - contentModel.getSubScene() - .setOnDragDropped(event -> { - Dragboard db = event.getDragboard(); - boolean success = false; - if (db.hasFiles()) { - File supportedFile = null; - fileLoop: for (File file : db.getFiles()) { - for (String format : supportedFormatRegex) { - if (file.getName() - .matches(format)) { - supportedFile = file; - break fileLoop; - } - } - } - if (supportedFile != null) { - // workaround for RT-30195 - if (supportedFile.getAbsolutePath() - .indexOf('%') != -1) { - supportedFile = new File(URLDecoder.decode(supportedFile.getAbsolutePath())); - } - load(supportedFile); - } - success = true; - } - event.setDropCompleted(success); - event.consume(); - }); - - sessionManager.bind(settingsBtn.selectedProperty(), "settingsBtn"); - sessionManager.bind(splitPane.getDividers() - .get(0) - .positionProperty(), - "settingsSplitPanePosition"); - sessionManager.bind(optimizeCheckBox.selectedProperty(), "optimize"); - sessionManager.bind(loadAsPolygonsCheckBox.selectedProperty(), - "loadAsPolygons"); - sessionManager.bind(loopBtn.selectedProperty(), "loop"); - - String url = sessionManager.getProperties() - .getProperty(Jfx3dViewerApp.FILE_URL_PROPERTY); - if (url == null) { - url = ContentModel.class.getResource("drop-here-large-yUp.obj") - .toExternalForm(); - } - - // do initial status update - updateStatus(); - } - - public void open(ActionEvent actionEvent) { - FileChooser chooser = new FileChooser(); - chooser.getExtensionFilters() - .add(new FileChooser.ExtensionFilter("Supported files", - Importer3D.getSupportedFormatExtensionFilters())); - if (loadedPath != null) { - chooser.setInitialDirectory(loadedPath.getAbsoluteFile() - .getParentFile()); - } - chooser.setTitle("Select file to load"); - File newFile = chooser.showOpenDialog(openMenuBtn.getScene() - .getWindow()); - if (newFile != null) { - load(newFile); - } - } - - public void toggleSettings(ActionEvent event) { - final SplitPane.Divider divider = splitPane.getDividers() - .get(0); - if (settingsBtn.isSelected()) { - if (settingsLastWidth == -1) { - settingsLastWidth = settingsPanel.prefWidth(-1); - } - final double divPos = 1 - - (settingsLastWidth / splitPane.getWidth()); - new Timeline(new KeyFrame(Duration.seconds(0.3), - event1 -> settingsPanel.setMinWidth(Region.USE_PREF_SIZE), - new KeyValue(divider.positionProperty(), - divPos, - Interpolator.EASE_BOTH))).play(); - } else { - settingsLastWidth = settingsPanel.getWidth(); - settingsPanel.setMinWidth(0); - new Timeline(new KeyFrame(Duration.seconds(0.3), - new KeyValue(divider.positionProperty(), - 1))).play(); - } - } - - private void doLoad(String fileUrl) { - loadedURL = fileUrl; - sessionManager.getProperties() - .setProperty(Jfx3dViewerApp.FILE_URL_PROPERTY, fileUrl); - try { - Pair content = Importer3D.loadIncludingAnimation(fileUrl, - loadAsPolygonsCheckBox.isSelected()); - Timeline timeline = content.getValue(); - Node root = content.getKey(); - if (optimizeCheckBox.isSelected()) { - new Optimizer(timeline, root, true).optimize(); - } - contentModel.setContent(root); - contentModel.setTimeline(timeline); - - if (timeline != null) { - timeline.setCycleCount(Animation.INDEFINITE); - timeline.play(); - } - } catch (IOException ex) { - Logger.getLogger(MainController.class.getName()) - .log(Level.SEVERE, null, ex); - } - updateStatus(); - } - - private void load(File file) { - loadedPath = file; - try { - doLoad(file.toURI() - .toURL() - .toString()); - } catch (Exception ex) { - Logger.getLogger(MainController.class.getName()) - .log(Level.SEVERE, null, ex); - } - } - - private void updateCount(Node node) { - nodeCount++; - if (node instanceof Parent) { - for (Node child : ((Parent) node).getChildrenUnmodifiable()) { - updateCount(child); - } - } else if (node instanceof Box) { - meshCount++; - triangleCount += 6 * 2; - } else if (node instanceof MeshView) { - TriangleMesh mesh = (TriangleMesh) ((MeshView) node).getMesh(); - if (mesh != null) { - meshCount++; - triangleCount += mesh.getFaces() - .size() - / mesh.getFaceElementSize(); - } - } - } - - private void updateStatus() { - nodeCount = 0; - meshCount = 0; - triangleCount = 0; - updateCount(contentModel.getRoot3D()); - Node content = contentModel.getContent(); - final Bounds bounds = content == null ? new BoundingBox(0, 0, 0, 0) - : content.getBoundsInLocal(); - status.setText(String.format("Nodes [%d] :: Meshes [%d] :: Triangles [%d] :: " - + "Bounds [w=%.2f,h=%.2f,d=%.2f]", - nodeCount, meshCount, triangleCount, - bounds.getWidth(), bounds.getHeight(), - bounds.getDepth())); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/NavigationController.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/NavigationController.java deleted file mode 100644 index cf5b49e..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/NavigationController.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.net.URL; -import java.util.ResourceBundle; - -import javafx.fxml.Initializable; -import javafx.scene.control.ScrollBar; - -/** - * Controller class for settings panel - */ -public class NavigationController implements Initializable { - // public FourWayNavControl eyeNav; - public ScrollBar zoomBar; - // public FourWayNavControl camNav; - private ContentModel contentModel = Jfx3dViewerApp.getContentModel(); - - @Override - public void initialize(URL location, ResourceBundle resources) { - zoomBar.setMin(-100); - zoomBar.setMax(0); - zoomBar.setValue(contentModel.getCameraPosition() - .getZ()); - zoomBar.setVisibleAmount(5); - contentModel.getCameraPosition() - .zProperty() - .bindBidirectional(zoomBar.valueProperty()); - // eyeNav.setListener(new FourWayNavControl.FourWayListener() { - // @Override public void navigateStep(Side direction, double amount) { - // switch (direction) { - // case TOP: - // contentModel.getCameraLookXRotate().setAngle(contentModel.getCameraLookXRotate().getAngle()+amount); - // break; - // case BOTTOM: - // contentModel.getCameraLookXRotate().setAngle(contentModel.getCameraLookXRotate().getAngle()-amount); - // break; - // case LEFT: - // contentModel.getCameraLookZRotate().setAngle(contentModel.getCameraLookZRotate().getAngle()-amount); - // break; - // case RIGHT: - // contentModel.getCameraLookZRotate().setAngle(contentModel.getCameraLookZRotate().getAngle()+amount); - // break; - // } - // } - // }); - // camNav.setListener(new FourWayNavControl.FourWayListener() { - // @Override public void navigateStep(Side direction, double amount) { - // switch (direction) { - // case TOP: - // contentModel.getCameraXRotate().setAngle(contentModel.getCameraXRotate().getAngle()-amount); - // break; - // case BOTTOM: - // contentModel.getCameraXRotate().setAngle(contentModel.getCameraXRotate().getAngle()+amount); - // break; - // case LEFT: - // contentModel.getCameraYRotate().setAngle(contentModel.getCameraYRotate().getAngle()+amount); - // break; - // case RIGHT: - // contentModel.getCameraYRotate().setAngle(contentModel.getCameraYRotate().getAngle()-amount); - // break; - // } - // } - // }); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SessionManager.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SessionManager.java deleted file mode 100644 index 40d0232..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SessionManager.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.DoubleProperty; -import javafx.beans.property.ObjectProperty; -import javafx.scene.control.Accordion; -import javafx.scene.control.TitledPane; -import javafx.scene.control.ToggleGroup; -import javafx.scene.paint.Color; - -public class SessionManager { - - private static final boolean ENABLE_SAVE_SESSION = true; - private static SessionManager sessionManager; - - public static SessionManager createSessionManager(String name) { - return sessionManager = new SessionManager(name); - } - - public static SessionManager getSessionManager() { - return sessionManager; - } - - public final String SESSION_PROPERTIES_FILENAME; - - private String name; - - private Properties props = new Properties(); - - private SessionManager(String name) { - this.name = name; - SESSION_PROPERTIES_FILENAME = name + "_session.properties"; - } - - public void bind(final Accordion accordion, final String propertyName) { - Object selectedPane = props.getProperty(propertyName); - for (TitledPane tp : accordion.getPanes()) { - if (tp.getText() != null && tp.getText() - .equals(selectedPane)) { - accordion.setExpandedPane(tp); - break; - } - } - accordion.expandedPaneProperty() - .addListener((ov, t, expandedPane) -> { - if (expandedPane != null) { - props.setProperty(propertyName, - expandedPane.getText()); - } - }); - } - - public void bind(final BooleanProperty property, - final String propertyName) { - String value = props.getProperty(propertyName); - if (value != null) { - property.set(Boolean.valueOf(value)); - } - property.addListener(o -> props.setProperty(propertyName, - property.getValue() - .toString())); - } - - public void bind(final DoubleProperty property, final String propertyName) { - String value = props.getProperty(propertyName); - if (value != null) { - property.set(Double.valueOf(value)); - } - property.addListener(o -> props.setProperty(propertyName, - property.getValue() - .toString())); - } - - public void bind(final ObjectProperty property, - final String propertyName) { - String value = props.getProperty(propertyName); - if (value != null) { - property.set(Color.valueOf(value)); - } - property.addListener(o -> props.setProperty(propertyName, - property.getValue() - .toString())); - } - - public void bind(final ToggleGroup toggleGroup, final String propertyName) { - try { - String value = props.getProperty(propertyName); - if (value != null) { - int selectedToggleIndex = Integer.parseInt(value); - toggleGroup.selectToggle(toggleGroup.getToggles() - .get(selectedToggleIndex)); - } - } catch (Exception ignored) { - } - toggleGroup.selectedToggleProperty() - .addListener(o -> { - if (toggleGroup.getSelectedToggle() == null) { - props.remove(propertyName); - } else { - props.setProperty(propertyName, - Integer.toString(toggleGroup.getToggles() - .indexOf(toggleGroup.getSelectedToggle()))); - } - }); - } - - public Properties getProperties() { - return props; - } - - public void loadSession() { - Reader reader = null; - try { - reader = new FileReader(SESSION_PROPERTIES_FILENAME); - props.load(reader); - } catch (FileNotFoundException ignored) { - } catch (IOException ex) { - Logger.getLogger(SessionManager.class.getName()) - .log(Level.SEVERE, null, ex); - } finally { - try { - if (reader != null) { - reader.close(); - } - } catch (IOException ex) { - Logger.getLogger(SessionManager.class.getName()) - .log(Level.SEVERE, null, ex); - } - } - } - - public void saveSession() { - if (ENABLE_SAVE_SESSION) { - try { - props.store(new FileWriter(SESSION_PROPERTIES_FILENAME), - name + " session properties"); - } catch (FileNotFoundException ignored) { - } catch (IOException ex) { - Logger.getLogger(SessionManager.class.getName()) - .log(Level.SEVERE, null, ex); - } - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SettingsController.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SettingsController.java deleted file mode 100644 index 23779ec..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SettingsController.java +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.net.URL; -import java.util.ResourceBundle; - -import com.javafx.experiments.shape3d.SubdivisionMesh; - -import javafx.application.Platform; -import javafx.beans.binding.Bindings; -import javafx.beans.binding.DoubleBinding; -import javafx.beans.binding.ObjectBinding; -import javafx.beans.property.DoubleProperty; -import javafx.fxml.Initializable; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.control.Accordion; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ColorPicker; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.control.Slider; -import javafx.scene.control.TitledPane; -import javafx.scene.control.ToggleGroup; -import javafx.scene.control.TreeItem; -import javafx.scene.control.TreeTableColumn; -import javafx.scene.control.TreeTableView; -import javafx.scene.control.cell.CheckBoxTreeTableCell; -import javafx.scene.control.cell.TextFieldTreeTableCell; -import javafx.scene.input.KeyCode; -import javafx.scene.paint.Color; -import javafx.scene.transform.Transform; -import javafx.util.StringConverter; - -/** - * Controller class for settings panel - */ -public class SettingsController implements Initializable { - private class Power10DoubleBinding extends DoubleBinding { - - private DoubleProperty prop; - - public Power10DoubleBinding(DoubleProperty prop) { - this.prop = prop; - bind(prop); - } - - @Override - protected double computeValue() { - return Math.pow(10, prop.getValue()); - } - } - - private class TreeItemImpl extends TreeItem { - - public TreeItemImpl(Node node) { - super(node); - if (node instanceof Parent) { - for (Node n : ((Parent) node).getChildrenUnmodifiable()) { - getChildren().add(new TreeItemImpl(n)); - } - } - node.setOnMouseClicked(t -> { - TreeItem parent = getParent(); - while (parent != null) { - parent.setExpanded(true); - parent = parent.getParent(); - } - hierarachyTreeTable.getSelectionModel() - .select(TreeItemImpl.this); - hierarachyTreeTable.scrollTo(hierarachyTreeTable.getSelectionModel() - .getSelectedIndex()); - t.consume(); - }); - } - } - - public ColorPicker ambientColorPicker; - public CheckBox ambientEnableCheckbox; - public ColorPicker backgroundColorPicker; - public TreeTableColumn depthColumn; - public Label farClipLabel; - public Slider farClipSlider; - public Slider fovSlider; - public TreeTableColumn heightColumn; - public TreeTableView hierarachyTreeTable; - public TreeTableColumn idColumn; - public ColorPicker light1ColorPicker; - public CheckBox light1EnabledCheckBox; - public CheckBox light1followCameraCheckBox; - public Slider light1x; - public Slider light1y; - public Slider light1z; - public ColorPicker light2ColorPicker; - public CheckBox light2EnabledCheckBox; - public Slider light2x; - public Slider light2y; - public Slider light2z; - public ColorPicker light3ColorPicker; - public CheckBox light3EnabledCheckBox; - public Slider light3x; - public Slider light3y; - public Slider light3z; - public CheckBox msaaCheckBox; - public Label nearClipLabel; - public Slider nearClipSlider; - public TreeTableColumn nodeColumn; - public Label selectedNodeLabel; - public Accordion settings; - public CheckBox showAxisCheckBox; - public ToggleGroup subdivisionBoundaryGroup; - public ToggleGroup subdivisionLevelGroup; - public ToggleGroup subdivisionSmoothGroup; - public ListView transformsList; - public TreeTableColumn visibilityColumn; - public TreeTableColumn widthColumn; - public CheckBox wireFrameCheckbox; - public TitledPane x6; - - public CheckBox yUpCheckBox; - - private final ContentModel contentModel = Jfx3dViewerApp.getContentModel(); - - @Override - public void initialize(URL location, ResourceBundle resources) { - // keep one pane open always - settings.expandedPaneProperty() - .addListener((observable, oldValue, - newValue) -> Platform.runLater(() -> { - if (settings.getExpandedPane() == null) { - settings.setExpandedPane(settings.getPanes() - .get(0)); - } - })); - // wire up settings in OPTIONS - contentModel.msaaProperty() - .bind(msaaCheckBox.selectedProperty()); - contentModel.showAxisProperty() - .bind(showAxisCheckBox.selectedProperty()); - contentModel.yUpProperty() - .bind(yUpCheckBox.selectedProperty()); - backgroundColorPicker.setValue((Color) contentModel.getSubScene() - .getFill()); - contentModel.getSubScene() - .fillProperty() - .bind(backgroundColorPicker.valueProperty()); - wireFrameCheckbox.selectedProperty() - .addListener((observable, oldValue, - isWireframe) -> contentModel.setWireFrame(isWireframe)); - subdivisionLevelGroup.selectedToggleProperty() - .addListener((observable, oldValue, - selectedToggle) -> { - if (selectedToggle == null - && oldValue != null) { - subdivisionLevelGroup.selectToggle(oldValue); - selectedToggle = oldValue; - } else { - contentModel.setSubdivisionLevel(Integer.parseInt((String) selectedToggle.getUserData())); - } - }); - subdivisionBoundaryGroup.selectedToggleProperty() - .addListener((observable, oldValue, - selectedToggle) -> { - if (selectedToggle == null - && oldValue != null) { - subdivisionBoundaryGroup.selectToggle(oldValue); - selectedToggle = oldValue; - } else { - contentModel.setBoundaryMode((SubdivisionMesh.BoundaryMode) selectedToggle.getUserData()); - } - }); - subdivisionSmoothGroup.selectedToggleProperty() - .addListener((observable, oldValue, - selectedToggle) -> { - if (selectedToggle == null - && oldValue != null) { - subdivisionSmoothGroup.selectToggle(oldValue); - selectedToggle = oldValue; - } else { - contentModel.setMapBorderMode((SubdivisionMesh.MapBorderMode) selectedToggle.getUserData()); - } - }); - // wire up settings in LIGHTS - ambientEnableCheckbox.setSelected(contentModel.getAmbientLightEnabled()); - contentModel.ambientLightEnabledProperty() - .bind(ambientEnableCheckbox.selectedProperty()); - ambientColorPicker.setValue(contentModel.getAmbientLight() - .getColor()); - contentModel.getAmbientLight() - .colorProperty() - .bind(ambientColorPicker.valueProperty()); - - // LIGHT 1 - light1EnabledCheckBox.setSelected(contentModel.getLight1Enabled()); - contentModel.light1EnabledProperty() - .bind(light1EnabledCheckBox.selectedProperty()); - light1ColorPicker.setValue(contentModel.getLight1() - .getColor()); - contentModel.getLight1() - .colorProperty() - .bind(light1ColorPicker.valueProperty()); - light1x.disableProperty() - .bind(light1followCameraCheckBox.selectedProperty()); - light1y.disableProperty() - .bind(light1followCameraCheckBox.selectedProperty()); - light1z.disableProperty() - .bind(light1followCameraCheckBox.selectedProperty()); - light1followCameraCheckBox.selectedProperty() - .addListener((observable, oldValue, - newValue) -> { - if (newValue) { - contentModel.getLight1() - .translateXProperty() - .bind(new DoubleBinding() { - { - bind(contentModel.getCamera() - .boundsInParentProperty()); - } - - @Override - protected double computeValue() { - return contentModel.getCamera() - .getBoundsInParent() - .getMinX(); - } - }); - contentModel.getLight1() - .translateYProperty() - .bind(new DoubleBinding() { - { - bind(contentModel.getCamera() - .boundsInParentProperty()); - } - - @Override - protected double computeValue() { - return contentModel.getCamera() - .getBoundsInParent() - .getMinY(); - } - }); - contentModel.getLight1() - .translateZProperty() - .bind(new DoubleBinding() { - { - bind(contentModel.getCamera() - .boundsInParentProperty()); - } - - @Override - protected double computeValue() { - return contentModel.getCamera() - .getBoundsInParent() - .getMinZ(); - } - }); - } else { - contentModel.getLight1() - .translateXProperty() - .bind(light1x.valueProperty()); - contentModel.getLight1() - .translateYProperty() - .bind(light1y.valueProperty()); - contentModel.getLight1() - .translateZProperty() - .bind(light1z.valueProperty()); - } - }); - // LIGHT 2 - light2EnabledCheckBox.setSelected(contentModel.getLight2Enabled()); - contentModel.light2EnabledProperty() - .bind(light2EnabledCheckBox.selectedProperty()); - light2ColorPicker.setValue(contentModel.getLight2() - .getColor()); - contentModel.getLight2() - .colorProperty() - .bind(light2ColorPicker.valueProperty()); - contentModel.getLight2() - .translateXProperty() - .bind(light2x.valueProperty()); - contentModel.getLight2() - .translateYProperty() - .bind(light2y.valueProperty()); - contentModel.getLight2() - .translateZProperty() - .bind(light2z.valueProperty()); - // LIGHT 3 - light3EnabledCheckBox.setSelected(contentModel.getLight3Enabled()); - contentModel.light3EnabledProperty() - .bind(light3EnabledCheckBox.selectedProperty()); - light3ColorPicker.setValue(contentModel.getLight3() - .getColor()); - contentModel.getLight3() - .colorProperty() - .bind(light3ColorPicker.valueProperty()); - contentModel.getLight3() - .translateXProperty() - .bind(light3x.valueProperty()); - contentModel.getLight3() - .translateYProperty() - .bind(light3y.valueProperty()); - contentModel.getLight3() - .translateZProperty() - .bind(light3z.valueProperty()); - // wire up settings in CAMERA - fovSlider.setValue(contentModel.getCamera() - .getFieldOfView()); - contentModel.getCamera() - .fieldOfViewProperty() - .bind(fovSlider.valueProperty()); - nearClipSlider.setValue(Math.log10(contentModel.getCamera() - .getNearClip())); - farClipSlider.setValue(Math.log10(contentModel.getCamera() - .getFarClip())); - nearClipLabel.textProperty() - .bind(Bindings.format(nearClipLabel.getText(), - contentModel.getCamera() - .nearClipProperty())); - farClipLabel.textProperty() - .bind(Bindings.format(farClipLabel.getText(), - contentModel.getCamera() - .farClipProperty())); - contentModel.getCamera() - .nearClipProperty() - .bind(new Power10DoubleBinding(nearClipSlider.valueProperty())); - contentModel.getCamera() - .farClipProperty() - .bind(new Power10DoubleBinding(farClipSlider.valueProperty())); - - hierarachyTreeTable.rootProperty() - .bind(new ObjectBinding>() { - - { - bind(contentModel.contentProperty()); - } - - @Override - protected TreeItem computeValue() { - Node content3D = contentModel.getContent(); - if (content3D != null) { - return new TreeItemImpl(content3D); - } else { - return null; - } - } - }); - hierarachyTreeTable.setOnMouseClicked(t -> { - if (t.getClickCount() == 2) { - settings.setExpandedPane(x6); - t.consume(); - } - }); - hierarachyTreeTable.setOnKeyPressed(t -> { - if (t.getCode() == KeyCode.SPACE) { - TreeItem selectedItem = hierarachyTreeTable.getSelectionModel() - .getSelectedItem(); - if (selectedItem != null) { - Node node = selectedItem.getValue(); - node.setVisible(!node.isVisible()); - } - t.consume(); - } - }); - x6.expandedProperty() - .addListener((ov, t, t1) -> { - if (t1) { - TreeItem selectedItem = hierarachyTreeTable.getSelectionModel() - .getSelectedItem(); - if (selectedItem == null) { - transformsList.setItems(null); - selectedNodeLabel.setText(""); - } else { - Node node = selectedItem.getValue(); - transformsList.setItems(node.getTransforms()); - selectedNodeLabel.setText(node.toString()); - } - } - }); - nodeColumn.setCellValueFactory(p -> p.getValue() - .valueProperty() - .asString()); - idColumn.setCellValueFactory(p -> p.getValue() - .getValue() - .idProperty()); - visibilityColumn.setCellValueFactory(p -> p.getValue() - .getValue() - .visibleProperty()); - visibilityColumn.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(visibilityColumn)); - widthColumn.setCellValueFactory(p -> new ObjectBinding() { - { - bind(p.getValue() - .getValue() - .boundsInLocalProperty()); - } - - @Override - protected Double computeValue() { - return p.getValue() - .getValue() - .getBoundsInLocal() - .getWidth(); - } - }); - StringConverter niceDoubleStringConverter = new StringConverter() { - @Override - public Double fromString(String string) { - throw new UnsupportedOperationException("Not supported yet."); //Not needed so far - } - - @Override - public String toString(Double t) { - return String.format("%.2f", t); - } - }; - widthColumn.setCellFactory(TextFieldTreeTableCell. forTreeTableColumn(niceDoubleStringConverter)); - heightColumn.setCellFactory(TextFieldTreeTableCell. forTreeTableColumn(niceDoubleStringConverter)); - depthColumn.setCellFactory(TextFieldTreeTableCell. forTreeTableColumn(niceDoubleStringConverter)); - heightColumn.setCellValueFactory(p -> new ObjectBinding() { - { - bind(p.getValue() - .getValue() - .boundsInLocalProperty()); - } - - @Override - protected Double computeValue() { - return p.getValue() - .getValue() - .getBoundsInLocal() - .getHeight(); - } - }); - depthColumn.setCellValueFactory(p -> new ObjectBinding() { - { - bind(p.getValue() - .getValue() - .boundsInLocalProperty()); - } - - @Override - protected Double computeValue() { - return p.getValue() - .getValue() - .getBoundsInLocal() - .getDepth(); - } - }); - - SessionManager sessionManager = SessionManager.getSessionManager(); - - sessionManager.bind(showAxisCheckBox.selectedProperty(), "showAxis"); - sessionManager.bind(yUpCheckBox.selectedProperty(), "yUp"); - sessionManager.bind(msaaCheckBox.selectedProperty(), "msaa"); - sessionManager.bind(wireFrameCheckbox.selectedProperty(), "wireFrame"); - sessionManager.bind(backgroundColorPicker.valueProperty(), - "backgroundColor"); - sessionManager.bind(fovSlider.valueProperty(), "fieldOfView"); - sessionManager.bind(subdivisionLevelGroup, "subdivisionLevel"); - sessionManager.bind(subdivisionBoundaryGroup, "subdivisionBoundary"); - sessionManager.bind(subdivisionSmoothGroup, "subdivisionSmooth"); - sessionManager.bind(light1ColorPicker.valueProperty(), "light1Color"); - sessionManager.bind(light1EnabledCheckBox.selectedProperty(), - "light1Enabled"); - sessionManager.bind(light1followCameraCheckBox.selectedProperty(), - "light1FollowCamera"); - sessionManager.bind(light1x.valueProperty(), "light1X"); - sessionManager.bind(light1y.valueProperty(), "light1Y"); - sessionManager.bind(light1z.valueProperty(), "light1Z"); - sessionManager.bind(light2ColorPicker.valueProperty(), "light2Color"); - sessionManager.bind(light2EnabledCheckBox.selectedProperty(), - "light2Enabled"); - sessionManager.bind(light2x.valueProperty(), "light2X"); - sessionManager.bind(light2y.valueProperty(), "light2Y"); - sessionManager.bind(light2z.valueProperty(), "light2Z"); - sessionManager.bind(light3ColorPicker.valueProperty(), "light3Color"); - sessionManager.bind(light3EnabledCheckBox.selectedProperty(), - "light3Enabled"); - sessionManager.bind(light3x.valueProperty(), "light3X"); - sessionManager.bind(light3y.valueProperty(), "light3Y"); - sessionManager.bind(light3z.valueProperty(), "light3Z"); - sessionManager.bind(ambientColorPicker.valueProperty(), "ambient"); - sessionManager.bind(ambientEnableCheckbox.selectedProperty(), - "ambientEnable"); - sessionManager.bind(settings, "settingsPane"); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SimpleViewerApp.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SimpleViewerApp.java deleted file mode 100644 index 8eb6d9c..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SimpleViewerApp.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -import com.javafx.experiments.importers.Importer3D; - -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; -import javafx.application.Application; -import javafx.scene.Group; -import javafx.scene.Node; -import javafx.scene.PerspectiveCamera; -import javafx.scene.Scene; -import javafx.scene.paint.Color; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Translate; -import javafx.stage.Stage; -import javafx.stage.StageStyle; -import javafx.util.Duration; - -/** - * JavaFX 3D Viewer Application - */ -public class SimpleViewerApp extends Application { - public static void main(String[] args) { - launch(args); - } - - private AutoScalingGroup autoScalingGroup = new AutoScalingGroup(2); - private final PerspectiveCamera camera = new PerspectiveCamera(true); - private final Rotate cameraLookXRotate = new Rotate(0, 0, 0, 0, - Rotate.X_AXIS); - private final Rotate cameraLookZRotate = new Rotate(0, 0, 0, 0, - Rotate.Z_AXIS); - private final Translate cameraPosition = new Translate(0, 0, -7); - private final Rotate cameraXRotate = new Rotate(-20, 0, 0, 0, - Rotate.X_AXIS); - private final Rotate cameraYRotate = new Rotate(-20, 0, 0, 0, - Rotate.Y_AXIS); - - private final Group root3D = new Group(); - - @Override - public void start(Stage stage) throws Exception { - List args = getParameters().getRaw(); - final Scene scene = new Scene(root3D, 1920, 1080, true); - scene.setFill(Color.TRANSPARENT); - stage.initStyle(StageStyle.TRANSPARENT); - - // CAMERA - camera.getTransforms() - .addAll(cameraXRotate, cameraYRotate, cameraPosition, - cameraLookXRotate, cameraLookZRotate); - camera.setNearClip(0.1); - camera.setFarClip(100); - scene.setCamera(camera); - root3D.getChildren() - .addAll(camera, autoScalingGroup); - - // LOAD DROP HERE MODEL - try { - Node content; - if (args.isEmpty()) { - content = Importer3D.load(ContentModel.class.getResource("drop-here.obj") - .toExternalForm()); - } else { - content = Importer3D.load(new File(args.get(0)).toURI() - .toURL() - .toExternalForm()); - } - autoScalingGroup.getChildren() - .add(content); - } catch (IOException e) { - e.printStackTrace(); - } - - Timeline timeline = new Timeline(new KeyFrame(Duration.ZERO, - new KeyValue(cameraYRotate.angleProperty(), - 0)), - new KeyFrame(Duration.seconds(4), - new KeyValue(cameraYRotate.angleProperty(), - 360))); - timeline.setCycleCount(Animation.INDEFINITE); - timeline.play(); - - stage.setScene(scene); - stage.show(); - - // MEASURE FPS - //TODO: RT-40270 - Public PerformanceTracker support should be added - // Timeline fpsTimeline = new Timeline(new KeyFrame(Duration.seconds(2), t -> - // System.out.println("fps = " + PerformanceTracker.getSceneTracker(scene).getInstantFPS()))); - // fpsTimeline.setCycleCount(Timeline.INDEFINITE); - // fpsTimeline.play(); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SubSceneResizer.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SubSceneResizer.java deleted file mode 100644 index 3e159bb..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/SubSceneResizer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.beans.property.ObjectProperty; -import javafx.scene.Node; -import javafx.scene.SubScene; -import javafx.scene.layout.Pane; - -/** - * Resizable container for a SubScene - */ -public class SubSceneResizer extends Pane { - private final Node controlsPanel; - private SubScene subScene; - - public SubSceneResizer(ObjectProperty subScene, - Node controlsPanel) { - this.subScene = subScene.get(); - this.controlsPanel = controlsPanel; - if (this.subScene != null) { - setPrefSize(this.subScene.getWidth(), this.subScene.getHeight()); - getChildren().add(this.subScene); - } - subScene.addListener((o, old, newSubScene) -> { - this.subScene = newSubScene; - if (this.subScene != null) { - setPrefSize(this.subScene.getWidth(), - this.subScene.getHeight()); - if (getChildren().size() == 1) { - getChildren().add(0, this.subScene); - } else { - getChildren().set(0, this.subScene); - } - } - }); - setMinSize(50, 50); - setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - getChildren().add(controlsPanel); - } - - public SubSceneResizer(SubScene subScene, Node controlsPanel) { - this.subScene = subScene; - this.controlsPanel = controlsPanel; - setPrefSize(subScene.getWidth(), subScene.getHeight()); - setMinSize(50, 50); - setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - getChildren().addAll(subScene, controlsPanel); - } - - @Override - protected void layoutChildren() { - final double width = getWidth(); - final double height = getHeight(); - if (subScene != null) { - subScene.setWidth(width); - subScene.setHeight(height); - } - final double controlsWidth = snapSize(controlsPanel.prefWidth(-1)); - final double controlsHeight = snapSize(controlsPanel.prefHeight(-1)); - controlsPanel.resizeRelocate(width - controlsWidth, 0, controlsWidth, - controlsHeight); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineController.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineController.java deleted file mode 100644 index 0b29c97..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineController.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.animation.Animation; -import javafx.animation.Timeline; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.value.ChangeListener; -import javafx.scene.control.Button; -import javafx.scene.control.ToggleButton; -import javafx.util.Duration; - -/** - * A controller class to bind up a timeline to play controler buttons - */ -public class TimelineController { - private final Button endBtn; - private final Button ffBtn; - - private final ToggleButton loopBtn; - - private final ToggleButton playBtn; - - private final ChangeListener rateListener; - - private final Button rwBtn; - private final Button startBtn; - private final SimpleObjectProperty timeline = new SimpleObjectProperty() { - private Timeline old; - - @Override - protected void invalidated() { - Timeline t = get(); - if (old != null) { - old.currentRateProperty() - .removeListener(rateListener); - } - if (t == null) { - startBtn.setDisable(true); - rwBtn.setDisable(true); - playBtn.setDisable(true); - ffBtn.setDisable(true); - endBtn.setDisable(true); - loopBtn.setDisable(true); - } else { - startBtn.setDisable(false); - rwBtn.setDisable(false); - playBtn.setDisable(false); - ffBtn.setDisable(false); - endBtn.setDisable(false); - loopBtn.setDisable(false); - playBtn.setSelected(t.getCurrentRate() != 0); - loopBtn.setSelected(t.getCycleDuration() - .equals(Animation.INDEFINITE)); - t.currentRateProperty() - .addListener(rateListener); - } - old = t; - } - }; - - public TimelineController(Button startBtn, Button rwBtn, - final ToggleButton playBtn, Button ffBtn, - Button endBtn, final ToggleButton loopBtn) { - this.startBtn = startBtn; - this.rwBtn = rwBtn; - this.playBtn = playBtn; - this.ffBtn = ffBtn; - this.endBtn = endBtn; - this.loopBtn = loopBtn; - - rateListener = (observable, oldValue, newRate) -> { - System.out.println("newRate = " + newRate); - if (newRate.intValue() == 0 && playBtn.isSelected()) { - playBtn.setSelected(false); - } - }; - - this.startBtn.setOnAction(event -> { - getTimeline().jumpTo(Duration.ZERO); - getTimeline().pause(); - }); - this.endBtn.setOnAction(event -> { - getTimeline().jumpTo(getTimeline().getTotalDuration()); - getTimeline().pause(); - }); - this.playBtn.setOnAction(event -> { - System.out.println("playBtn.isSelected() = " - + playBtn.isSelected()); - if (playBtn.isSelected()) { // currently paused so play - getTimeline().play(); - } else { // currently playing so pause - getTimeline().pause(); - } - }); - this.ffBtn.setOnMousePressed(event -> getTimeline().setRate(2)); - this.ffBtn.setOnMouseReleased(event -> getTimeline().setRate(1)); - this.rwBtn.setOnMousePressed(event -> getTimeline().setRate(-2)); - this.rwBtn.setOnMouseReleased(event -> getTimeline().setRate(1)); - this.loopBtn.setOnAction(event -> { - System.out.println("LOOP CHANGE TO " + loopBtn.isSelected() - + " before=" + getTimeline().getCycleCount()); - if (loopBtn.isSelected()) { - getTimeline().stop(); - getTimeline().setCycleCount(Animation.INDEFINITE); - getTimeline().play(); - } else { - getTimeline().stop(); - getTimeline().setCycleCount(1); - getTimeline().play(); - } - System.out.println(" after = " + getTimeline().getCycleCount()); - }); - } - - public Timeline getTimeline() { - return timeline.get(); - } - - public void setTimeline(Timeline timeline) { - this.timeline.set(timeline); - } - - public SimpleObjectProperty timelineProperty() { - return timeline; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineDisplay.java b/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineDisplay.java deleted file mode 100644 index ff063b8..0000000 --- a/gui/src/main/java/com/javafx/experiments/jfx3dviewer/TimelineDisplay.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.jfx3dviewer; - -import javafx.animation.Timeline; -import javafx.beans.binding.DoubleBinding; -import javafx.beans.binding.StringBinding; -import javafx.beans.property.SimpleDoubleProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.scene.layout.Region; -import javafx.scene.text.Text; - -/** - * Visual display for timeline play head and length - */ -public class TimelineDisplay extends Region { - private final Region background = new Region(); - private final Region bar = new Region(); - - private final Text current = new Text(); - - private SimpleDoubleProperty currentTimeAsPercentage = new SimpleDoubleProperty(0) { - @Override - protected void invalidated() { - requestLayout(); - } - }; - - private final Text end = new Text(); - - private final Region progress = new Region(); - private final Text start = new Text("0s"); - private final SimpleObjectProperty timeline = new SimpleObjectProperty() { - private Timeline old; - - @Override - protected void invalidated() { - final Timeline t = get(); - if (old != null) { - currentTimeAsPercentage.unbind(); - end.textProperty() - .unbind(); - } - if (t == null) { - setVisible(false); - } else { - setVisible(true); - currentTimeAsPercentage.bind(new DoubleBinding() { - { - bind(t.currentTimeProperty(), - t.cycleDurationProperty()); - } - - @Override - protected double computeValue() { - return t.getCurrentTime() - .toMillis() - / t.getCycleDuration() - .toMillis(); - } - }); - end.textProperty() - .bind(new StringBinding() { - { - bind(t.cycleDurationProperty()); - } - - @Override - protected String computeValue() { - return String.format("%.2fs", - t.getCycleDuration() - .toSeconds()); - } - }); - current.textProperty() - .bind(new StringBinding() { - { - bind(t.currentTimeProperty()); - } - - @Override - protected String computeValue() { - return String.format("%.2fs", - t.getCurrentTime() - .toSeconds()); - } - }); - } - old = t; - } - }; - - public TimelineDisplay() { - getStyleClass().add("timeline-display"); - background.getStyleClass() - .add("background"); - background.setCache(true); // cache so we don't have to render shadow every frame - bar.getStyleClass() - .add("bar"); - progress.getStyleClass() - .add("progress"); - getChildren().addAll(background, start, current, end, bar, progress); - } - - public Timeline getTimeline() { - return timeline.get(); - } - - public void setTimeline(Timeline timeline) { - this.timeline.set(timeline); - } - - public SimpleObjectProperty timelineProperty() { - return timeline; - } - - @Override - protected double computePrefHeight(double width) { - return 24; - } - - @Override - protected double computePrefWidth(double height) { - return 200; - } - - @Override - protected void layoutChildren() { - final double w = getWidth() - snappedLeftInset() - snappedRightInset(); - background.resizeRelocate(0, 0, getWidth(), getHeight()); - bar.resizeRelocate(snappedLeftInset(), snappedTopInset(), w, 6); - progress.resizeRelocate(snappedLeftInset(), snappedTopInset(), - w * currentTimeAsPercentage.get(), 6); - start.setLayoutX(snappedLeftInset()); - start.setLayoutY(getHeight() - snappedBottomInset()); - current.setLayoutX((int) ((getWidth() - current.getLayoutBounds() - .getWidth()) - / 2d)); - current.setLayoutY(getHeight() - snappedBottomInset()); - end.setLayoutX(getWidth() - snappedRightInset() - end.getLayoutBounds() - .getWidth()); - end.setLayoutY(getHeight() - snappedBottomInset()); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMesh.java b/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMesh.java deleted file mode 100644 index 0a933e9..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMesh.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableFloatArray; -import javafx.collections.ObservableIntegerArray; - -/** - * A Mesh where each face can be a Polygon - * - * can convert to using ObservableIntegerArray - */ -public class PolygonMesh { - private static final int NUM_COMPONENTS_PER_FACE = 6; - // TODO: Hardcode to constants for FX 8 (only one vertex format) - private static final int NUM_COMPONENTS_PER_POINT = 3; - private static final int NUM_COMPONENTS_PER_TEXCOORD = 2; - public int[][] faces = new int[0][0]; - protected int numEdgesInFaces = -1; // TODO invalidate automatically by listening to faces (whenever it is an observable) - - private final ObservableIntegerArray faceSmoothingGroups = FXCollections.observableIntegerArray(); - - private final ObservableFloatArray points = FXCollections.observableFloatArray(); - - private final ObservableFloatArray texCoords = FXCollections.observableFloatArray(); - - public PolygonMesh() { - } - - public PolygonMesh(float[] points, float[] texCoords, int[][] faces) { - this.points.addAll(points); - this.texCoords.addAll(texCoords); - this.faces = faces; - } - - public int getFaceElementSize() { - return NUM_COMPONENTS_PER_FACE; - } - - public ObservableIntegerArray getFaceSmoothingGroups() { - return faceSmoothingGroups; - } - - public int getNumEdgesInFaces() { - if (numEdgesInFaces == -1) { - numEdgesInFaces = 0; - for (int[] face : faces) { - numEdgesInFaces += face.length; - } - numEdgesInFaces /= 2; - } - return numEdgesInFaces; - } - - public int getPointElementSize() { - return NUM_COMPONENTS_PER_POINT; - } - - public ObservableFloatArray getPoints() { - return points; - } - - public int getTexCoordElementSize() { - return NUM_COMPONENTS_PER_TEXCOORD; - } - - public ObservableFloatArray getTexCoords() { - return texCoords; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMeshView.java b/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMeshView.java deleted file mode 100644 index 422fd4e..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/PolygonMeshView.java +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d; - -import java.util.Arrays; - -import com.javafx.experiments.shape3d.SubdivisionMesh.BoundaryMode; -import com.javafx.experiments.shape3d.SubdivisionMesh.MapBorderMode; - -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleIntegerProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.collections.ArrayChangeListener; -import javafx.collections.ObservableFloatArray; -import javafx.scene.Parent; -import javafx.scene.paint.Material; -import javafx.scene.shape.CullFace; -import javafx.scene.shape.DrawMode; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.TriangleMesh; - -/** - * A MeshView node for Polygon Meshes - */ -public class PolygonMeshView extends Parent { - private static final boolean DEBUG = false; - /** - * Texture mapping boundary rule for Catmull Clark subdivision applied to - * the mesh - * - * @defaultValue BoundaryMode.CREASE_EDGES - */ - private SimpleObjectProperty boundaryMode; - - /** - * Defines the drawMode this {@code Shape3D}. - * - * @defaultValue CullFace.BACK - */ - private ObjectProperty cullFace; - - /** - * Defines the drawMode this {@code Shape3D}. - * - * @defaultValue DrawMode.FILL - */ - private ObjectProperty drawMode; - - private boolean facesDirty = true; - /** - * Texture mapping smoothness option for Catmull Clark subdivision applied - * to the mesh - * - * @defaultValue MapBorderMode.NOT_SMOOTH - */ - private SimpleObjectProperty mapBorderMode; - - /** - * Defines the material this {@code Shape3D}. The default material is null. - * If {@code Material} is null, a PhongMaterial with a diffuse color of - * Color.LIGHTGRAY is used for rendering. - * - * @defaultValue null - */ - private ObjectProperty materialProperty = new SimpleObjectProperty(); - private final ArrayChangeListener meshPointsListener = (t, - bln, - i, - i1) -> { - pointsDirty = true; - updateMesh(); - }; - /** - * Specifies the 3D mesh data of this {@code MeshView}. - * - * @defaultValue null - */ - private ObjectProperty meshProperty; - private final ArrayChangeListener meshTexCoordListener = (t, - bln, - i, - i1) -> { - texCoordsDirty = true; - updateMesh(); - }; - - // ========================================================================= - // PROPERTIES - - private final MeshView meshView = new MeshView(); - - private boolean pointsDirty = true; - - private boolean pointsSizeDirty = true; - - /** - * Number of iterations of Catmull Clark subdivision to apply to the mesh - * - * @defaultValue 0 - */ - private SimpleIntegerProperty subdivisionLevelProperty; - - // this is null if no subdivision is happening (i.e. subdivisionLevel = 0); - private SubdivisionMesh subdivisionMesh; - - private boolean texCoordsDirty = true; - - private TriangleMesh triangleMesh = new TriangleMesh(); - - public PolygonMeshView() { - meshView.materialProperty() - .bind(materialProperty()); - getChildren().add(meshView); - } - - public PolygonMeshView(PolygonMesh mesh) { - this(); - setMesh(mesh); - } - - public SimpleObjectProperty boundaryModeProperty() { - if (boundaryMode == null) { - boundaryMode = new SimpleObjectProperty(getBoundaryMode()) { - @Override - protected void invalidated() { - if (subdivisionMesh != null) { - subdivisionMesh.setBoundaryMode(getBoundaryMode()); - subdivisionMesh.update(); - } - pointsDirty = true; - updateMesh(); - } - }; - } - return boundaryMode; - } - - public final ObjectProperty cullFaceProperty() { - if (cullFace == null) { - cullFace = new SimpleObjectProperty(PolygonMeshView.this, - "cullFace", - CullFace.BACK) { - @Override - protected void invalidated() { - meshView.setCullFace(get()); - } - }; - } - return cullFace; - } - - public final ObjectProperty drawModeProperty() { - if (drawMode == null) { - drawMode = new SimpleObjectProperty(PolygonMeshView.this, - "drawMode", - DrawMode.FILL) { - @Override - protected void invalidated() { - meshView.setDrawMode(get()); - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = true; - updateMesh(); - } - }; - } - return drawMode; - } - - public BoundaryMode getBoundaryMode() { - return boundaryMode == null ? BoundaryMode.CREASE_EDGES - : boundaryMode.get(); - } - - public final CullFace getCullFace() { - return cullFace == null ? CullFace.BACK : cullFace.get(); - } - - public final DrawMode getDrawMode() { - return drawMode == null ? DrawMode.FILL : drawMode.get(); - } - - public MapBorderMode getMapBorderMode() { - return mapBorderMode == null ? MapBorderMode.NOT_SMOOTH - : mapBorderMode.get(); - } - - public Material getMaterial() { - return materialProperty.get(); - } - - public PolygonMesh getMesh() { - return meshProperty().get(); - } - - public int getSubdivisionLevel() { - return subdivisionLevelProperty == null ? 0 - : subdivisionLevelProperty.get(); - } - - public SimpleObjectProperty mapBorderModeProperty() { - if (mapBorderMode == null) { - mapBorderMode = new SimpleObjectProperty(getMapBorderMode()) { - @Override - protected void invalidated() { - if (subdivisionMesh != null) { - subdivisionMesh.setMapBorderMode(getMapBorderMode()); - subdivisionMesh.update(); - } - texCoordsDirty = true; - updateMesh(); - } - }; - } - return mapBorderMode; - } - - public ObjectProperty materialProperty() { - return materialProperty; - } - - public ObjectProperty meshProperty() { - if (meshProperty == null) { - meshProperty = new SimpleObjectProperty(); - meshProperty.addListener((observable, oldValue, newValue) -> { - if (oldValue != null) { - oldValue.getPoints() - .removeListener(meshPointsListener); - oldValue.getPoints() - .removeListener(meshTexCoordListener); - } - - meshProperty.set(newValue); - - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = true; - updateMesh(); - - if (newValue != null) { - newValue.getPoints() - .addListener(meshPointsListener); - newValue.getTexCoords() - .addListener(meshTexCoordListener); - } - }); - } - return meshProperty; - } - - public void setBoundaryMode(BoundaryMode boundaryMode) { - boundaryModeProperty().set(boundaryMode); - } - - public final void setCullFace(CullFace value) { - cullFaceProperty().set(value); - } - - public final void setDrawMode(DrawMode value) { - drawModeProperty().set(value); - } - - public void setMapBorderMode(MapBorderMode mapBorderMode) { - mapBorderModeProperty().set(mapBorderMode); - } - - public void setMaterial(Material material) { - materialProperty.set(material); - } - - public void setMesh(PolygonMesh mesh) { - meshProperty().set(mesh); - } - - // ========================================================================= - // CONSTRUCTORS - - public void setSubdivisionLevel(int subdivisionLevel) { - subdivisionLevelProperty().set(subdivisionLevel); - } - - public SimpleIntegerProperty subdivisionLevelProperty() { - if (subdivisionLevelProperty == null) { - subdivisionLevelProperty = new SimpleIntegerProperty(getSubdivisionLevel()) { - @Override - protected void invalidated() { - // create SubdivisionMesh if subdivisionLevel is greater than 0 - if ((getSubdivisionLevel() > 0) - && (subdivisionMesh == null)) { - subdivisionMesh = new SubdivisionMesh(getMesh(), - getSubdivisionLevel(), - getBoundaryMode(), - getMapBorderMode()); - subdivisionMesh.getOriginalMesh() - .getPoints() - .addListener((t, bln, i, - i1) -> subdivisionMesh.update()); - setMesh(subdivisionMesh); - } - if (subdivisionMesh != null) { - subdivisionMesh.setSubdivisionLevel(getSubdivisionLevel()); - subdivisionMesh.update(); - } - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = true; - updateMesh(); - } - }; - } - return subdivisionLevelProperty; - } - - // ========================================================================= - // PRIVATE METHODS - - private float distanceBetweenPoints(float x1, float y1, float z1, float x2, - float y2, float z2) { - return (float) Math.sqrt(Math.pow(z2 - z1, 2) + Math.pow(x2 - x1, 2) - + Math.pow(y2 - y1, 2)); - } - - private void updateMesh() { - PolygonMesh pmesh = getMesh(); - if (pmesh == null || pmesh.faces == null) { - triangleMesh = new TriangleMesh(); - meshView.setMesh(triangleMesh); - return; - } - - final int pointElementSize = triangleMesh.getPointElementSize(); - final int faceElementSize = triangleMesh.getFaceElementSize(); - final boolean isWireframe = getDrawMode() == DrawMode.LINE; - if (DEBUG) { - System.out.println("UPDATE MESH -- " - + (isWireframe ? "WIREFRAME" : "SOLID")); - } - final int numOfPoints = pmesh.getPoints() - .size() - / pointElementSize; - if (DEBUG) { - System.out.println("numOfPoints = " + numOfPoints); - } - - if (isWireframe) { - // The current triangleMesh implementation gives buggy behavior when the size of faces are shrunken - // Create a new TriangleMesh as a work around - // [JIRA] (RT-31178) - if (texCoordsDirty || facesDirty || pointsSizeDirty) { - triangleMesh = new TriangleMesh(); - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = true; // to fill in the new triangle mesh - } - if (facesDirty) { - facesDirty = false; - // create faces for each edge - int[] facesArray = new int[pmesh.getNumEdgesInFaces() - * faceElementSize]; - int facesInd = 0; - int pointsInd = pmesh.getPoints() - .size(); - for (int[] face : pmesh.faces) { - if (DEBUG) { - System.out.println("face.length = " + (face.length / 2) - + " -- " + Arrays.toString(face)); - } - int lastPointIndex = face[face.length - 2]; - if (DEBUG) { - System.out.println(" lastPointIndex = " - + lastPointIndex); - } - for (int p = 0; p < face.length; p += 2) { - int pointIndex = face[p]; - if (DEBUG) { - System.out.println(" connecting point[" - + lastPointIndex + "] to point[" - + pointIndex + "]"); - } - facesArray[facesInd++] = lastPointIndex; - facesArray[facesInd++] = 0; - facesArray[facesInd++] = pointIndex; - facesArray[facesInd++] = 0; - facesArray[facesInd++] = pointsInd / pointElementSize; - facesArray[facesInd++] = 0; - if (DEBUG) { - System.out.println(" facesInd = " - + facesInd); - } - pointsInd += pointElementSize; - lastPointIndex = pointIndex; - } - } - triangleMesh.getFaces() - .setAll(facesArray); - triangleMesh.getFaceSmoothingGroups() - .clear(); - } - if (texCoordsDirty) { - texCoordsDirty = false; - // set simple texCoords for wireframe - triangleMesh.getTexCoords() - .setAll(0, 0); - } - if (pointsDirty) { - pointsDirty = false; - // create points and copy over points to the first part of the array - float[] pointsArray = new float[pmesh.getPoints() - .size() - + pmesh.getNumEdgesInFaces() - * 3]; - pmesh.getPoints() - .copyTo(0, pointsArray, 0, pmesh.getPoints() - .size()); - - // add point for each edge - int pointsInd = pmesh.getPoints() - .size(); - for (int[] face : pmesh.faces) { - int lastPointIndex = face[face.length - 2]; - for (int p = 0; p < face.length; p += 2) { - int pointIndex = face[p]; - // get start and end point - final float x1 = pointsArray[lastPointIndex - * pointElementSize]; - final float y1 = pointsArray[lastPointIndex - * pointElementSize + 1]; - final float z1 = pointsArray[lastPointIndex - * pointElementSize + 2]; - final float x2 = pointsArray[pointIndex - * pointElementSize]; - final float y2 = pointsArray[pointIndex - * pointElementSize + 1]; - final float z2 = pointsArray[pointIndex - * pointElementSize + 2]; - final float distance = Math.abs(distanceBetweenPoints(x1, - y1, - z1, - x2, - y2, - z2)); - final float offset = distance / 1000; - // add new point - pointsArray[pointsInd++] = x2 + offset; - pointsArray[pointsInd++] = y2 + offset; - pointsArray[pointsInd++] = z2 + offset; - lastPointIndex = pointIndex; - } - } - triangleMesh.getPoints() - .setAll(pointsArray); - } - } else { - // The current triangleMesh implementation gives buggy behavior when the size of faces are shrunken - // Create a new TriangleMesh as a work around - // [JIRA] (RT-31178) - if (texCoordsDirty || facesDirty || pointsSizeDirty) { - triangleMesh = new TriangleMesh(); - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = true; // to fill in the new triangle mesh - } - if (facesDirty) { - facesDirty = false; - // create faces and break into triangles - final int numOfFacesBefore = pmesh.faces.length; - final int numOfFacesAfter = pmesh.getNumEdgesInFaces() - - 2 * numOfFacesBefore; - int[] facesArray = new int[numOfFacesAfter * faceElementSize]; - int[] smoothingGroupsArray = new int[numOfFacesAfter]; - int facesInd = 0; - for (int f = 0; f < pmesh.faces.length; f++) { - int[] face = pmesh.faces[f]; - int currentSmoothGroup = pmesh.getFaceSmoothingGroups() - .get(f); - if (DEBUG) { - System.out.println("face.length = " + face.length - + " -- " + Arrays.toString(face)); - } - int firstPointIndex = face[0]; - int firstTexIndex = face[1]; - int lastPointIndex = face[2]; - int lastTexIndex = face[3]; - for (int p = 4; p < face.length; p += 2) { - int pointIndex = face[p]; - int texIndex = face[p + 1]; - facesArray[facesInd - * faceElementSize] = firstPointIndex; - facesArray[facesInd * faceElementSize - + 1] = firstTexIndex; - facesArray[facesInd * faceElementSize - + 2] = lastPointIndex; - facesArray[facesInd * faceElementSize - + 3] = lastTexIndex; - facesArray[facesInd * faceElementSize + 4] = pointIndex; - facesArray[facesInd * faceElementSize + 5] = texIndex; - smoothingGroupsArray[facesInd] = currentSmoothGroup; - facesInd++; - lastPointIndex = pointIndex; - lastTexIndex = texIndex; - } - } - triangleMesh.getFaces() - .setAll(facesArray); - triangleMesh.getFaceSmoothingGroups() - .setAll(smoothingGroupsArray); - } - if (texCoordsDirty) { - texCoordsDirty = false; - triangleMesh.getTexCoords() - .setAll(pmesh.getTexCoords()); - } - if (pointsDirty) { - pointsDirty = false; - triangleMesh.getPoints() - .setAll(pmesh.getPoints()); - } - } - - if (DEBUG) { - System.out.println("CREATING TRIANGLE MESH"); - } - if (DEBUG) { - System.out.println(" points = " - + Arrays.toString(((TriangleMesh) meshView.getMesh()).getPoints() - .toArray(null))); - } - if (DEBUG) { - System.out.println(" texCoords = " - + Arrays.toString(((TriangleMesh) meshView.getMesh()).getTexCoords() - .toArray(null))); - } - if (DEBUG) { - System.out.println(" faces = " - + Arrays.toString(((TriangleMesh) meshView.getMesh()).getFaces() - .toArray(null))); - } - - if (meshView.getMesh() != triangleMesh) { - meshView.setMesh(triangleMesh); - } - pointsDirty = pointsSizeDirty = texCoordsDirty = facesDirty = false; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/SkinningMesh.java b/gui/src/main/java/com/javafx/experiments/shape3d/SkinningMesh.java deleted file mode 100644 index cce4e8d..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/SkinningMesh.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.javafx.experiments.importers.maya.Joint; - -import javafx.beans.InvalidationListener; -import javafx.collections.ObservableFloatArray; -import javafx.geometry.Point3D; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.transform.Affine; -import javafx.scene.transform.MatrixType; -import javafx.scene.transform.NonInvertibleTransformException; -import javafx.scene.transform.Transform; - -/** - * PolygonMesh that knows how to update itself given changes in joint - * transforms. The mesh can be updated with an AnimationTimer. - */ -public class SkinningMesh extends PolygonMesh { - private class JointIndex { - public List children = new ArrayList(); - public int index; - public Transform localToGlobalTransform; - public Node node; - public JointIndex parent = null; - - public JointIndex(Node n, int ind, List orderedJoints) { - node = n; - index = ind; - if (node instanceof Parent) { - for (Node childJoint : ((Parent) node).getChildrenUnmodifiable()) { - if (childJoint instanceof Parent) { // is childJoint a joint or a node with children? - int childInd = orderedJoints.indexOf(childJoint); - JointIndex childJointIndex = new JointIndex(childJoint, - childInd, - orderedJoints); - childJointIndex.parent = this; - children.add(childJointIndex); - } - } - } - } - } - - private Transform bindGlobalInverseTransform; - private final List jointIndexForest; - private boolean jointsTransformDirty = true; - private final Transform[] jointToRootTransforms; // the root refers to the group containing all the mesh skinning nodes (i.e. the parent of jointForest) - private final int nJoints; - private final int nPoints; - private final float[][] relativePoints; // nJoints x nPoints*3 - private final List[] weightIndices; - - private final float[][] weights; // nJoints x nPoints - - /** - * SkinningMesh constructor - * - * @param mesh - * The binding mesh - * @param weights - * A two-dimensional array (nJoints x nPoints) of the influence - * weights used for skinning - * @param bindTransforms - * The binding transforms for every joint - * @param bindGlobalTransform - * The global binding transform; all binding transforms are - * defined with respect to this frame - * @param joints - * A list of joints used for skinning; the order of these are - * associated with the respective attributes of @weights - * and @bindTransforms - * @param jointForest - * A list of the top level trees that contain the joints; all - * the @joints should be contained in this forest - */ - @SuppressWarnings("unchecked") - public SkinningMesh(PolygonMesh mesh, float[][] weights, - Affine[] bindTransforms, Affine bindGlobalTransform, - List joints, List jointForest) { - this.getPoints() - .addAll(mesh.getPoints()); - this.getTexCoords() - .addAll(mesh.getTexCoords()); - this.faces = mesh.faces; - this.getFaceSmoothingGroups() - .addAll(mesh.getFaceSmoothingGroups()); - - this.weights = weights; - - nJoints = joints.size(); - nPoints = getPoints().size() / getPointElementSize(); - - // Create the jointIndexForest forest. Its structure is the same as - // jointForest, except that this forest have indices information and - // some branches are pruned if they don't contain joints. - jointIndexForest = new ArrayList(jointForest.size()); - for (Parent jointRoot : jointForest) { - jointIndexForest.add(new JointIndex(jointRoot, - joints.indexOf(jointRoot), - joints)); - } - - try { - bindGlobalInverseTransform = bindGlobalTransform.createInverse(); - } catch (NonInvertibleTransformException ex) { - System.err.println("Caught NonInvertibleTransformException: " - + ex.getMessage()); - } - - jointToRootTransforms = new Transform[nJoints]; - - // For optimization purposes, store the indices of the non-zero weights - weightIndices = new List[nJoints]; - for (int j = 0; j < nJoints; j++) { - weightIndices[j] = new ArrayList(); - for (int i = 0; i < nPoints; i++) { - if (weights[j][i] != 0.0f) { - weightIndices[j].add(new Integer(i)); - } - } - } - - // Compute the points of the binding mesh relative to the binding transforms - ObservableFloatArray points = getPoints(); - relativePoints = new float[nJoints][nPoints * 3]; - for (int j = 0; j < nJoints; j++) { - Transform postBindTransform = bindTransforms[j].createConcatenation(bindGlobalTransform); - for (int i = 0; i < nPoints; i++) { - Point3D relativePoint = postBindTransform.transform(points.get(3 - * i), - points.get(3 - * i - + 1), - points.get(3 - * i - + 2)); - relativePoints[j][3 * i] = (float) relativePoint.getX(); - relativePoints[j][3 * i + 1] = (float) relativePoint.getY(); - relativePoints[j][3 * i + 2] = (float) relativePoint.getZ(); - } - } - - // Add a listener to all the joints (and their parents nodes) so that we can track when any of their transforms have changed - // Set of joints that already have a listener (so we don't attach a listener to the same node more than once) - Set processedNodes = new HashSet(joints.size()); - InvalidationListener invalidationListener = observable -> jointsTransformDirty = true; - for (int j = 0; j < joints.size(); j++) { - Node node = joints.get(j); - while (!processedNodes.contains(node)) { - node.localToParentTransformProperty() - .addListener(invalidationListener); - processedNodes.add(node); - // Don't check for nodes above the jointForest - if (jointForest.contains(node)) { - break; - } - node = node.getParent(); - } - } - } - - // Updates its points only if any of the joints' transforms have changed - public void update() { - if (!jointsTransformDirty) { - return; - } - - updateLocalToGlobalTransforms(jointIndexForest); - - float[] points = new float[nPoints * 3]; - double[] t = new double[12]; - float[] relativePoint; - for (int j = 0; j < nJoints; j++) { - jointToRootTransforms[j].toArray(MatrixType.MT_3D_3x4, t); - relativePoint = relativePoints[j]; - for (Integer i : weightIndices[j]) { - points[3 * i] += weights[j][i] - * (t[0] * relativePoint[3 * i] - + t[1] * relativePoint[3 * i + 1] - + t[2] * relativePoint[3 * i + 2] + t[3]); - points[3 * i - + 1] += weights[j][i] - * (t[4] * relativePoint[3 * i] - + t[5] * relativePoint[3 * i + 1] - + t[6] * relativePoint[3 * i + 2] + t[7]); - points[3 * i - + 2] += weights[j][i] - * (t[8] * relativePoint[3 * i] - + t[9] * relativePoint[3 * i + 1] - + t[10] * relativePoint[3 * i + 2] + t[11]); - } - } - getPoints().set(0, points, 0, points.length); - - jointsTransformDirty = false; - } - - // Updates the jointToRootTransforms by doing a a depth-first search of the jointIndexForest - private void updateLocalToGlobalTransforms(List jointIndexForest) { - for (JointIndex jointIndex : jointIndexForest) { - if (jointIndex.parent == null) { - jointIndex.localToGlobalTransform = bindGlobalInverseTransform.createConcatenation(jointIndex.node.getLocalToParentTransform()); - } else { - jointIndex.localToGlobalTransform = jointIndex.parent.localToGlobalTransform.createConcatenation(jointIndex.node.getLocalToParentTransform()); - } - if (jointIndex.index != -1) { - jointToRootTransforms[jointIndex.index] = jointIndex.localToGlobalTransform; - } - updateLocalToGlobalTransforms(jointIndex.children); - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/SubdivisionMesh.java b/gui/src/main/java/com/javafx/experiments/shape3d/SubdivisionMesh.java deleted file mode 100644 index 3df2169..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/SubdivisionMesh.java +++ /dev/null @@ -1,205 +0,0 @@ - -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */package com.javafx.experiments.shape3d; - -import java.util.ArrayList; -import java.util.List; - -import com.javafx.experiments.shape3d.symbolic.SymbolicPolygonMesh; -import com.javafx.experiments.shape3d.symbolic.SymbolicSubdivisionBuilder; - -/** - * Catmull Clark subdivision surface polygon mesh - */ -public class SubdivisionMesh extends PolygonMesh { - /** - * Describes whether the edges and points at the boundary are treated as - * creases - */ - public enum BoundaryMode { - /** - * Edges and points at the boundary are treated as creases - */ - CREASE_ALL, - /** - * Only edges at the boundary are treated as creases - */ - CREASE_EDGES - } - - /** - * Describes how the new texture coordinate for the control point is defined - */ - public enum MapBorderMode { - /** - * Jeeps the same uvs for all control points - */ - NOT_SMOOTH, - /** - * Smooths uvs of points at boundaries and original control points (and - * creases [in the future when creases are defined]) - */ - SMOOTH_ALL, - /** - * Smooths uvs of points at corners - */ - SMOOTH_INTERNAL - } - - private BoundaryMode boundaryMode; - private MapBorderMode mapBorderMode; - private boolean meshDirty; - - private final PolygonMesh originalMesh; - private boolean pointValuesDirty; - private int subdivisionLevel; - - private boolean subdivisionLevelDirty; - - private final List symbolicMeshes; - - public SubdivisionMesh(PolygonMesh originalMesh, int subdivisionLevel, - BoundaryMode boundaryMode, - MapBorderMode mapBorderMode) { - this.originalMesh = originalMesh; - setSubdivisionLevelForced(subdivisionLevel); - setBoundaryModeForced(boundaryMode); - setMapBorderModeForced(mapBorderMode); - - symbolicMeshes = new ArrayList<>(4); // the polymesh is usually subdivided up to 3 times - - originalMesh.getPoints() - .addListener((observableArray, sizeChanged, from, to) -> { - if (sizeChanged) { - meshDirty = true; - } else { - pointValuesDirty = true; - } - }); - originalMesh.getTexCoords() - .addListener((observableArray, sizeChanged, from, - to) -> meshDirty = true); - } - - public SubdivisionMesh.BoundaryMode getBoundaryMode() { - return boundaryMode; - } - - public SubdivisionMesh.MapBorderMode getMapBorderMode() { - return mapBorderMode; - } - - public PolygonMesh getOriginalMesh() { - return originalMesh; - } - - public int getSubdivisionLevel() { - return subdivisionLevel; - } - - public void setBoundaryMode(SubdivisionMesh.BoundaryMode boundaryMode) { - if (boundaryMode != this.boundaryMode) { - setBoundaryModeForced(boundaryMode); - } - } - - public void setMapBorderMode(SubdivisionMesh.MapBorderMode mapBorderMode) { - if (mapBorderMode != this.mapBorderMode) { - setMapBorderModeForced(mapBorderMode); - } - } - - public void setSubdivisionLevel(int subdivisionLevel) { - if (subdivisionLevel != this.subdivisionLevel) { - setSubdivisionLevelForced(subdivisionLevel); - } - } - - /** - * Updates the variables of the underlying polygon mesh. It only updates the - * fields that need to be updated. - */ - public void update() { - if (meshDirty) { - symbolicMeshes.clear(); - symbolicMeshes.add(new SymbolicPolygonMesh(originalMesh)); - pointValuesDirty = true; - subdivisionLevelDirty = true; - } - - while (subdivisionLevel >= symbolicMeshes.size()) { - symbolicMeshes.add(SymbolicSubdivisionBuilder.subdivide(symbolicMeshes.get(symbolicMeshes.size() - - 1), - boundaryMode, - mapBorderMode)); - pointValuesDirty = true; - subdivisionLevelDirty = true; - } - - if (pointValuesDirty) { - for (int i = 0; i <= subdivisionLevel; i++) { - SymbolicPolygonMesh symbolicMesh = symbolicMeshes.get(i); - symbolicMesh.points.update(); - } - } - - if (pointValuesDirty || subdivisionLevelDirty) { - getPoints().setAll(symbolicMeshes.get(subdivisionLevel).points.data); - } - - if (subdivisionLevelDirty) { - faces = symbolicMeshes.get(subdivisionLevel).faces; - numEdgesInFaces = -1; - getFaceSmoothingGroups().setAll(symbolicMeshes.get(subdivisionLevel).faceSmoothingGroups); - getTexCoords().setAll(symbolicMeshes.get(subdivisionLevel).texCoords); - } - - meshDirty = false; - pointValuesDirty = false; - subdivisionLevelDirty = false; - } - - private void setBoundaryModeForced(SubdivisionMesh.BoundaryMode boundaryMode) { - this.boundaryMode = boundaryMode; - meshDirty = true; - } - - private void setMapBorderModeForced(SubdivisionMesh.MapBorderMode mapBorderMode) { - this.mapBorderMode = mapBorderMode; - meshDirty = true; - } - - private void setSubdivisionLevelForced(int subdivisionLevel) { - this.subdivisionLevel = subdivisionLevel; - subdivisionLevelDirty = true; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/OriginalPointArray.java b/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/OriginalPointArray.java deleted file mode 100644 index 2ab31a4..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/OriginalPointArray.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d.symbolic; - -import com.javafx.experiments.shape3d.PolygonMesh; - -public class OriginalPointArray extends SymbolicPointArray { - PolygonMesh mesh; - - public OriginalPointArray(PolygonMesh mesh) { - super(new float[mesh.getPoints() - .size()]); - this.mesh = mesh; - } - - @Override - public void update() { - mesh.getPoints() - .copyTo(0, data, 0, data.length); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SubdividedPointArray.java b/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SubdividedPointArray.java deleted file mode 100644 index e399fdc..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SubdividedPointArray.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d.symbolic; - -import java.util.Arrays; - -import com.javafx.experiments.shape3d.SubdivisionMesh; - -public class SubdividedPointArray extends SymbolicPointArray { - private final SubdivisionMesh.BoundaryMode boundaryMode; - private final float[][] controlFactors; // factors corresponding to controlPoints - private final int[][] controlInds; // indices corresponding to controlPoints - private final float[] controlPoints; // points of the previous subdivision level - private int currPoint = 0; - - private final float[][] factors; - - private final int[][] inds; - - public SubdividedPointArray(SymbolicPointArray controlPointArray, - int numPoints, - SubdivisionMesh.BoundaryMode boundaryMode) { - super(new float[NUM_COMPONENTS_PER_POINT * numPoints]); - - this.controlPoints = controlPointArray.data; - this.controlInds = new int[numPoints][]; - this.controlFactors = new float[numPoints][]; - this.inds = new int[numPoints][]; - this.factors = new float[numPoints][]; - - this.boundaryMode = boundaryMode; - } - - public int addControlPoint(int[] facePoints, int[] edgePoints, - int[] fromEdgePoints, int[] toEdgePoints, - boolean[] isEdgeBoundary, int origPoint, - boolean isBoundary, boolean hasInternalEdge) { - if (isBoundary) { - if ((boundaryMode == SubdivisionMesh.BoundaryMode.CREASE_EDGES) - || hasInternalEdge) { - controlInds[currPoint] = new int[] { origPoint }; - controlFactors[currPoint] = new float[] { 0.5f }; - - int numBoundaryEdges = 0; - for (int i = 0; i < edgePoints.length; i++) { - if (isEdgeBoundary[i]) { - numBoundaryEdges++; - } - } - inds[currPoint] = new int[numBoundaryEdges]; - factors[currPoint] = new float[numBoundaryEdges]; - int boundaryEdgeInd = 0; - for (int i = 0; i < edgePoints.length; i++) { - if (isEdgeBoundary[i]) { - inds[currPoint][boundaryEdgeInd] = edgePoints[i]; - factors[currPoint][boundaryEdgeInd] = 0.25f; - boundaryEdgeInd++; - } - } - } else { - controlInds[currPoint] = new int[] { origPoint }; - controlFactors[currPoint] = new float[] { 1.0f }; - - inds[currPoint] = new int[0]; - factors[currPoint] = new float[0]; - } - } else { - int n = facePoints.length; - - controlInds[currPoint] = new int[1 + edgePoints.length * 2]; - controlFactors[currPoint] = new float[1 + edgePoints.length * 2]; - controlInds[currPoint][0] = origPoint; - controlFactors[currPoint][0] = (n - 3.0f) / n; - for (int i = 0; i < edgePoints.length; i++) { - controlInds[currPoint][1 + 2 * i] = fromEdgePoints[i]; - controlFactors[currPoint][1 + 2 * i] = 1.0f / (n * n); - controlInds[currPoint][1 + 2 * i + 1] = toEdgePoints[i]; - controlFactors[currPoint][1 + 2 * i + 1] = 1.0f / (n * n); - } - - inds[currPoint] = facePoints; - factors[currPoint] = new float[facePoints.length]; - Arrays.fill(factors[currPoint], 1.0f / (n * n)); - } - return currPoint++; - } - - public int addEdgePoint(int[] facePoints, int fromPoint, int toPoint, - boolean isBoundary) { - if (isBoundary) { - controlInds[currPoint] = new int[] { fromPoint, toPoint }; - controlFactors[currPoint] = new float[] { 0.5f, 0.5f }; - - inds[currPoint] = new int[0]; - factors[currPoint] = new float[0]; - } else { - int n = facePoints.length + 2; - controlInds[currPoint] = new int[] { fromPoint, toPoint }; - controlFactors[currPoint] = new float[] { 1.0f / n, 1.0f / n }; - - inds[currPoint] = facePoints; - factors[currPoint] = new float[facePoints.length]; - Arrays.fill(factors[currPoint], 1.0f / n); - } - return currPoint++; - } - - public int addFacePoint(int[] vertices) { - controlInds[currPoint] = vertices; - controlFactors[currPoint] = new float[vertices.length]; - Arrays.fill(controlFactors[currPoint], 1.0f / vertices.length); - - inds[currPoint] = new int[0]; - factors[currPoint] = new float[0]; - - return currPoint++; - } - - @Override - public void update() { - int ci; - float f; - float x, y, z; - for (int i = 0; i < numPoints; i++) { - x = y = z = 0.0f; - for (int j = 0; j < controlInds[i].length; j++) { - ci = 3 * controlInds[i][j]; - f = controlFactors[i][j]; - x += controlPoints[ci] * f; - y += controlPoints[ci + 1] * f; - z += controlPoints[ci + 2] * f; - } - for (int j = 0; j < inds[i].length; j++) { - ci = 3 * inds[i][j]; - f = factors[i][j]; - x += data[ci] * f; - y += data[ci + 1] * f; - z += data[ci + 2] * f; - } - data[3 * i] = x; - data[3 * i + 1] = y; - data[3 * i + 2] = z; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPointArray.java b/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPointArray.java deleted file mode 100644 index fd0d5b6..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPointArray.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d.symbolic; - -/** - * A 3D geometric point array that has the x, y, z coordinates of every point as - * a function of other variables. - */ -public abstract class SymbolicPointArray { - // x, y, z as stated. - static final int NUM_COMPONENTS_PER_POINT = 3; - final public float[] data; - final public int numPoints; - - protected SymbolicPointArray(float[] data) { - this.data = data; - this.numPoints = data.length / NUM_COMPONENTS_PER_POINT; - } - - /** - * Updates the variables x, y, z based on the state of the other variables - * that this symbolic point depends on. - */ - public abstract void update(); -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPolygonMesh.java b/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPolygonMesh.java deleted file mode 100644 index 3d2b2d1..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicPolygonMesh.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d.symbolic; - -import com.javafx.experiments.shape3d.PolygonMesh; - -/** - * Polygon mesh where the points are symbolic. That is, the values of the points - * depend on other variables and they can be updated appropriately. - */ -public class SymbolicPolygonMesh { - public int[][] faces; - public int[] faceSmoothingGroups; - public SymbolicPointArray points; - public float[] texCoords; - private int numEdgesInFaces = -1; - - public SymbolicPolygonMesh(PolygonMesh mesh) { - this.points = new OriginalPointArray(mesh); - this.texCoords = mesh.getTexCoords() - .toArray(this.texCoords); - this.faces = mesh.faces; - this.faceSmoothingGroups = mesh.getFaceSmoothingGroups() - .toArray(null); - } - - public SymbolicPolygonMesh(SymbolicPointArray points, float[] texCoords, - int[][] faces, int[] faceSmoothingGroups) { - this.points = points; - this.texCoords = texCoords; - this.faces = faces; - this.faceSmoothingGroups = faceSmoothingGroups; - } - - public int getNumEdgesInFaces() { - if (numEdgesInFaces == -1) { - numEdgesInFaces = 0; - for (int[] face : faces) { - numEdgesInFaces += face.length; - } - numEdgesInFaces /= 2; - } - return numEdgesInFaces; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicSubdivisionBuilder.java b/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicSubdivisionBuilder.java deleted file mode 100644 index a916341..0000000 --- a/gui/src/main/java/com/javafx/experiments/shape3d/symbolic/SymbolicSubdivisionBuilder.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.shape3d.symbolic; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.javafx.experiments.shape3d.SubdivisionMesh.BoundaryMode; -import com.javafx.experiments.shape3d.SubdivisionMesh.MapBorderMode; - -import javafx.geometry.Point2D; - -/** - * - * Data structure builder for Catmull Clark subdivision surface - */ -public class SymbolicSubdivisionBuilder { - - private static class Edge { - int from, to; - - public Edge(int from, int to) { - this.from = Math.min(from, to); - this.to = Math.max(from, to); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Edge other = (Edge) obj; - if (this.from != other.from) { - return false; - } - if (this.to != other.to) { - return false; - } - return true; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 41 * hash + this.from; - hash = 41 * hash + this.to; - return hash; - } - } - - private static class EdgeInfo { - Edge edge; - int edgePoint; - List faces = new ArrayList<>(2); - - /** - * an edge is in the boundary if it has only one adjacent face - */ - public boolean isBoundary() { - return faces.size() == 1; - } - } - - private static class FaceInfo { - Edge[] edges; - Point2D[] edgeTexCoords; - int facePoint; - int newTexCoordIndex; - Point2D texCoord; - - public FaceInfo(int n) { - edges = new Edge[n]; - edgeTexCoords = new Point2D[n]; - } - } - - private class PointInfo { - Set edges = new HashSet<>(4); - List faces = new ArrayList<>(4); - - /** - * A point is internal if at least one of its adjacent edges is not in - * the boundary - */ - public boolean hasInternalEdge() { - for (Edge edge : edges) { - EdgeInfo edgeInfo = edgeInfos.get(edge); - if (!edgeInfo.isBoundary()) { - return true; - } - } - return false; - } - - /** - * A point is in the boundary if any of its adjacent edges is in the - * boundary - */ - public boolean isBoundary() { - for (Edge edge : edges) { - EdgeInfo edgeInfo = edgeInfos.get(edge); - if (edgeInfo.isBoundary()) { - return true; - } - } - return false; - } - } - - public static SymbolicPolygonMesh subdivide(SymbolicPolygonMesh oldMesh, - BoundaryMode boundaryMode, - MapBorderMode mapBorderMode) { - SymbolicSubdivisionBuilder subdivision = new SymbolicSubdivisionBuilder(oldMesh, - boundaryMode, - mapBorderMode); - return subdivision.subdivide(); - } - - private BoundaryMode boundaryMode; - private Map edgeInfos; - private FaceInfo[] faceInfos; - private MapBorderMode mapBorderMode; - private int newTexCoordIndex; - - private SymbolicPolygonMesh oldMesh; - - private PointInfo[] pointInfos; - - private SubdividedPointArray points; - - private int[] reindex; - - private float[] texCoords; - - public SymbolicSubdivisionBuilder(SymbolicPolygonMesh oldMesh, - BoundaryMode boundaryMode, - MapBorderMode mapBorderMode) { - this.oldMesh = oldMesh; - this.boundaryMode = boundaryMode; - this.mapBorderMode = mapBorderMode; - } - - public SymbolicPolygonMesh subdivide() { - collectInfo(); - - texCoords = new float[(oldMesh.getNumEdgesInFaces() * 3 - + oldMesh.faces.length) - * 2]; - int[][] faces = new int[oldMesh.getNumEdgesInFaces()][8]; - int[] faceSmoothingGroups = new int[oldMesh.getNumEdgesInFaces()]; - newTexCoordIndex = 0; - reindex = new int[oldMesh.points.numPoints]; // indexes incremented by 1, 0 reserved for empty - - // face points first - int newFacesInd = 0; - for (int f = 0; f < oldMesh.faces.length; f++) { - FaceInfo faceInfo = faceInfos[f]; - int[] oldFaces = oldMesh.faces[f]; - for (int p = 0; p < oldFaces.length; p += 2) { - faces[newFacesInd][4] = getPointNewIndex(faceInfo); - faces[newFacesInd][5] = getTexCoordNewIndex(faceInfo); - faceSmoothingGroups[newFacesInd] = oldMesh.faceSmoothingGroups[f]; - newFacesInd++; - } - } - // then, add edge points - newFacesInd = 0; - for (int f = 0; f < oldMesh.faces.length; f++) { - FaceInfo faceInfo = faceInfos[f]; - int[] oldFaces = oldMesh.faces[f]; - for (int p = 0; p < oldFaces.length; p += 2) { - faces[newFacesInd][2] = getPointNewIndex(faceInfo, - (p / 2 - + 1) % faceInfo.edges.length); - faces[newFacesInd][3] = getTexCoordNewIndex(faceInfo, - (p / 2 - + 1) % faceInfo.edges.length); - faces[newFacesInd][6] = getPointNewIndex(faceInfo, p / 2); - faces[newFacesInd][7] = getTexCoordNewIndex(faceInfo, p / 2); - newFacesInd++; - } - } - // finally, add control points - newFacesInd = 0; - for (int f = 0; f < oldMesh.faces.length; f++) { - FaceInfo faceInfo = faceInfos[f]; - int[] oldFaces = oldMesh.faces[f]; - for (int p = 0; p < oldFaces.length; p += 2) { - faces[newFacesInd][0] = getPointNewIndex(oldFaces[p]); - faces[newFacesInd][1] = getTexCoordNewIndex(faceInfo, - oldFaces[p], - oldFaces[p + 1]); - newFacesInd++; - } - } - - SymbolicPolygonMesh newMesh = new SymbolicPolygonMesh(points, texCoords, - faces, - faceSmoothingGroups); - return newMesh; - } - - private void addEdge(Edge edge, FaceInfo faceInfo) { - EdgeInfo edgeInfo = edgeInfos.get(edge); - if (edgeInfo == null) { - edgeInfo = new EdgeInfo(); - edgeInfo.edge = edge; - edgeInfos.put(edge, edgeInfo); - } - edgeInfo.faces.add(faceInfo); - } - - private void addPoint(int point, Edge edge) { - PointInfo pointInfo = pointInfos[point]; - if (pointInfo == null) { - pointInfo = new PointInfo(); - pointInfos[point] = pointInfo; - } - pointInfo.edges.add(edge); - } - - private void addPoint(int point, FaceInfo faceInfo, Edge edge) { - PointInfo pointInfo = pointInfos[point]; - if (pointInfo == null) { - pointInfo = new PointInfo(); - pointInfos[point] = pointInfo; - } - pointInfo.edges.add(edge); - pointInfo.faces.add(faceInfo); - } - - private int calcControlPoint(int srcPointIndex) { - PointInfo pointInfo = pointInfos[srcPointIndex]; - int origPoint = srcPointIndex; - - int[] facePoints = new int[pointInfo.faces.size()]; - for (int f = 0; f < facePoints.length; f++) { - facePoints[f] = pointInfo.faces.get(f).facePoint; - } - int[] edgePoints = new int[pointInfo.edges.size()]; - boolean[] isEdgeBoundary = new boolean[pointInfo.edges.size()]; - int[] fromEdgePoints = new int[pointInfo.edges.size()]; - int[] toEdgePoints = new int[pointInfo.edges.size()]; - int i = 0; - for (Edge edge : pointInfo.edges) { - EdgeInfo edgeInfo = edgeInfos.get(edge); - edgePoints[i] = edgeInfo.edgePoint; - isEdgeBoundary[i] = edgeInfo.isBoundary(); - fromEdgePoints[i] = edgeInfo.edge.from; - toEdgePoints[i] = edgeInfo.edge.to; - i++; - } - int destPointIndex = points.addControlPoint(facePoints, edgePoints, - fromEdgePoints, - toEdgePoints, - isEdgeBoundary, origPoint, - pointInfo.isBoundary(), - pointInfo.hasInternalEdge()); - return destPointIndex; - } - - private void calcControlTexCoord(FaceInfo faceInfo, int srcPointIndex, - int srcTexCoordIndex, - int destTexCoordIndex) { - PointInfo pointInfo = pointInfos[srcPointIndex]; - boolean pointBelongsToCrease = oldMesh.points instanceof OriginalPointArray; - if ((mapBorderMode == MapBorderMode.SMOOTH_ALL - && (pointInfo.isBoundary() || pointBelongsToCrease)) - || (mapBorderMode == MapBorderMode.SMOOTH_INTERNAL - && !pointInfo.hasInternalEdge())) { - double u = oldMesh.texCoords[srcTexCoordIndex * 2] / 2; - double v = oldMesh.texCoords[srcTexCoordIndex * 2 + 1] / 2; - for (int i = 0; i < faceInfo.edges.length; i++) { - if ((faceInfo.edges[i].to == srcPointIndex) - || (faceInfo.edges[i].from == srcPointIndex)) { - u += faceInfo.edgeTexCoords[i].getX() / 4; - v += faceInfo.edgeTexCoords[i].getY() / 4; - } - } - texCoords[destTexCoordIndex * 2] = (float) u; - texCoords[destTexCoordIndex * 2 + 1] = (float) v; - } else { - texCoords[destTexCoordIndex - * 2] = oldMesh.texCoords[srcTexCoordIndex * 2]; - texCoords[destTexCoordIndex * 2 - + 1] = oldMesh.texCoords[srcTexCoordIndex * 2 + 1]; - } - } - - private void collectInfo() { - edgeInfos = new HashMap<>(oldMesh.faces.length * 2); - faceInfos = new FaceInfo[oldMesh.faces.length]; - pointInfos = new PointInfo[oldMesh.points.numPoints]; - - for (int f = 0; f < oldMesh.faces.length; f++) { - int[] face = oldMesh.faces[f]; - int n = face.length / 2; - FaceInfo faceInfo = new FaceInfo(n); - faceInfos[f] = faceInfo; - if (n < 3) { - continue; - } - int from = face[(n - 1) * 2]; - int texFrom = face[(n - 1) * 2 + 1]; - double fu, fv; - double tu, tv; - double u = 0, v = 0; - fu = oldMesh.texCoords[texFrom * 2]; - fv = oldMesh.texCoords[texFrom * 2 + 1]; - for (int i = 0; i < n; i++) { - int to = face[i * 2]; - int texTo = face[i * 2 + 1]; - tu = oldMesh.texCoords[texTo * 2]; - tv = oldMesh.texCoords[texTo * 2 + 1]; - Point2D midTexCoord = new Point2D((fu + tu) / 2, (fv + tv) / 2); - Edge edge = new Edge(from, to); - faceInfo.edges[i] = edge; - faceInfo.edgeTexCoords[i] = midTexCoord; - addEdge(edge, faceInfo); - addPoint(to, faceInfo, edge); - addPoint(from, edge); - fu = tu; - fv = tv; - u += tu / n; - v += tv / n; - from = to; - texFrom = texTo; - } - faceInfo.texCoord = new Point2D(u, v); - } - - points = new SubdividedPointArray(oldMesh.points, - oldMesh.points.numPoints - + faceInfos.length - + edgeInfos.size(), - boundaryMode); - - for (int f = 0; f < oldMesh.faces.length; f++) { - int[] face = oldMesh.faces[f]; - int n = face.length / 2; - int[] faceVertices = new int[n]; - for (int i = 0; i < n; i++) { - faceVertices[i] = face[i * 2]; - } - faceInfos[f].facePoint = points.addFacePoint(faceVertices); - } - - for (EdgeInfo edgeInfo : edgeInfos.values()) { - int[] edgeFacePoints = new int[edgeInfo.faces.size()]; - for (int f = 0; f < edgeInfo.faces.size(); f++) { - edgeFacePoints[f] = edgeInfo.faces.get(f).facePoint; - } - edgeInfo.edgePoint = points.addEdgePoint(edgeFacePoints, - edgeInfo.edge.from, - edgeInfo.edge.to, - edgeInfo.isBoundary()); - } - } - - private int getPointNewIndex(FaceInfo faceInfo) { - return faceInfo.facePoint; - } - - private int getPointNewIndex(FaceInfo faceInfo, int edgeInd) { - Edge edge = faceInfo.edges[edgeInd]; - EdgeInfo edgeInfo = edgeInfos.get(edge); - return edgeInfo.edgePoint; - } - - private int getPointNewIndex(int srcPointIndex) { - int destPointIndex = reindex[srcPointIndex] - 1; - if (destPointIndex == -1) { - destPointIndex = calcControlPoint(srcPointIndex); - reindex[srcPointIndex] = destPointIndex + 1; - } - return destPointIndex; - } - - private int getTexCoordNewIndex(FaceInfo faceInfo) { - int destTexCoordIndex = faceInfo.newTexCoordIndex - 1; - if (destTexCoordIndex == -1) { - destTexCoordIndex = newTexCoordIndex; - faceInfo.newTexCoordIndex = destTexCoordIndex + 1; - newTexCoordIndex++; - texCoords[destTexCoordIndex * 2] = (float) faceInfo.texCoord.getX(); - texCoords[destTexCoordIndex * 2 - + 1] = (float) faceInfo.texCoord.getY(); - } - return destTexCoordIndex; - } - - private int getTexCoordNewIndex(FaceInfo faceInfo, int edgeInd) { - int destTexCoordIndex = newTexCoordIndex; - newTexCoordIndex++; - texCoords[destTexCoordIndex - * 2] = (float) faceInfo.edgeTexCoords[edgeInd].getX(); - texCoords[destTexCoordIndex * 2 - + 1] = (float) faceInfo.edgeTexCoords[edgeInd].getY(); - return destTexCoordIndex; - } - - private int getTexCoordNewIndex(FaceInfo faceInfo, int srcPointIndex, - int srcTexCoordIndex) { - int destTexCoordIndex = newTexCoordIndex; - newTexCoordIndex++; - calcControlTexCoord(faceInfo, srcPointIndex, srcTexCoordIndex, - destTexCoordIndex); - return destTexCoordIndex; - } -} \ No newline at end of file diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/DragSupport.java b/gui/src/main/java/com/javafx/experiments/utils3d/DragSupport.java deleted file mode 100644 index 99ab71b..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/DragSupport.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package com.javafx.experiments.utils3d; - -import javafx.beans.property.Property; -import javafx.event.EventHandler; -import javafx.geometry.Orientation; -import javafx.scene.Scene; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.MouseButton; -import javafx.scene.input.MouseEvent; - -/** - * Utility class that binds simple mouse gestures to number properties so that - * their values can be controlled with mouse drag events. - */ -public class DragSupport { - public EventHandler keyboardEventHandler; - public EventHandler mouseEventHandler; - private Number anchor; - private double dragAnchor; - private MouseEvent lastMouseEvent; - private Scene target; - - public DragSupport(Scene target, final KeyCode modifier, - MouseButton mouseButton, final Orientation orientation, - final Property property) { - this(target, modifier, mouseButton, orientation, property, 1); - } - - public DragSupport(Scene target, final KeyCode modifier, - final MouseButton mouseButton, - final Orientation orientation, - final Property property, final double factor) { - this.target = target; - mouseEventHandler = t -> { - if (t.getEventType() != MouseEvent.MOUSE_ENTERED_TARGET - && t.getEventType() != MouseEvent.MOUSE_EXITED_TARGET) { - lastMouseEvent = t; - } - if (t.getEventType() == MouseEvent.MOUSE_PRESSED) { - if (t.getButton() == mouseButton - && isModifierCorrect(t, modifier)) { - anchor = property.getValue(); - dragAnchor = getCoord(t, orientation); - t.consume(); - } - } else if (t.getEventType() == MouseEvent.MOUSE_DRAGGED) { - if (t.getButton() == mouseButton - && isModifierCorrect(t, modifier)) { - property.setValue(anchor.doubleValue() - + (getCoord(t, orientation) - dragAnchor) - * factor); - t.consume(); - } - } - }; - keyboardEventHandler = t -> { - if (t.getEventType() == KeyEvent.KEY_PRESSED) { - if (t.getCode() == modifier) { - anchor = property.getValue(); - if (lastMouseEvent != null) { - dragAnchor = getCoord(lastMouseEvent, orientation); - } - t.consume(); - } - } else if (t.getEventType() == KeyEvent.KEY_RELEASED) { - if (t.getCode() != modifier && isModifierCorrect(t, modifier)) { - anchor = property.getValue(); - if (lastMouseEvent != null) { - dragAnchor = getCoord(lastMouseEvent, orientation); - } - t.consume(); - } - } - }; - target.addEventHandler(MouseEvent.ANY, mouseEventHandler); - target.addEventHandler(KeyEvent.ANY, keyboardEventHandler); - } - - /** - * Creates DragSupport instance that attaches EventHandlers to the given - * scene and responds to mouse and keyboard events in order to change given - * property values according to mouse drag events of given orientation - * - * @param target - * scene - * @param modifier - * null if no modifier needed - * @param orientation - * vertical or horizontal - * @param property - * number property to control - * @see #DragSupport(javafx.scene.Scene, javafx.scene.input.KeyCode, - * javafx.geometry.Orientation, javafx.beans.property.Property, double) - */ - public DragSupport(Scene target, final KeyCode modifier, - final Orientation orientation, - final Property property) { - this(target, modifier, MouseButton.PRIMARY, orientation, property, 1); - } - - /** - * Creates DragSupport instance that attaches EventHandlers to the given - * scene and responds to mouse and keyboard events in order to change given - * property values according to mouse drag events of given orientation. - * Mouse movement amount is multiplied by given factor. - * - * @param target - * scene - * @param modifier - * null if no modifier needed - * @param orientation - * vertical or horizontal - * @param property - * number property to control - * @param factor - * multiplier for mouse movement amount - */ - public DragSupport(Scene target, final KeyCode modifier, - final Orientation orientation, - final Property property, final double factor) { - this(target, modifier, MouseButton.PRIMARY, orientation, property, - factor); - } - - /** - * Removes event handlers of this DragSupport instance from the target scene - */ - public void detach() { - target.removeEventHandler(MouseEvent.ANY, mouseEventHandler); - target.removeEventHandler(KeyEvent.ANY, keyboardEventHandler); - } - - private double getCoord(MouseEvent t, Orientation orientation) { - switch (orientation) { - case HORIZONTAL: - return t.getScreenX(); - case VERTICAL: - return t.getScreenY(); - default: - throw new IllegalArgumentException("This orientation is not supported: " - + orientation); - } - } - - private boolean isModifierCorrect(KeyEvent t, KeyCode keyCode) { - return (keyCode != KeyCode.ALT ^ t.isAltDown()) - && (keyCode != KeyCode.CONTROL ^ t.isControlDown()) - && (keyCode != KeyCode.SHIFT ^ t.isShiftDown()) - && (keyCode != KeyCode.META ^ t.isMetaDown()); - } - - private boolean isModifierCorrect(MouseEvent t, KeyCode keyCode) { - return (keyCode != KeyCode.ALT ^ t.isAltDown()) - && (keyCode != KeyCode.CONTROL ^ t.isControlDown()) - && (keyCode != KeyCode.SHIFT ^ t.isShiftDown()) - && (keyCode != KeyCode.META ^ t.isMetaDown()); - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/animation/NumberTangentInterpolator.java b/gui/src/main/java/com/javafx/experiments/utils3d/animation/NumberTangentInterpolator.java deleted file mode 100644 index 52317a0..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/animation/NumberTangentInterpolator.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.animation; - -import javafx.animation.Interpolator; -import javafx.util.Duration; - -public class NumberTangentInterpolator extends Interpolator { - - private final long inTicks, outTicks; - private final double inValue, outValue; - - public NumberTangentInterpolator(Duration duration, double value) { - this.outTicks = this.inTicks = TickCalculation.fromDuration(duration); - this.inValue = this.outValue = value; - } - - public NumberTangentInterpolator(Duration inDuration, double inValue, - Duration outDuration, double outValue) { - this.inTicks = TickCalculation.fromDuration(inDuration); - this.inValue = inValue; - this.outTicks = TickCalculation.fromDuration(outDuration); - this.outValue = outValue; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final NumberTangentInterpolator other = (NumberTangentInterpolator) obj; - if (Double.doubleToLongBits(this.inValue) != Double.doubleToLongBits(other.inValue)) { - return false; - } - if (Double.doubleToLongBits(this.outValue) != Double.doubleToLongBits(other.outValue)) { - return false; - } - if (this.inTicks != other.inTicks) { - return false; - } - if (this.outTicks != other.outTicks) { - return false; - } - return true; - } - - public double getInTicks() { - return inTicks; - } - - public double getInValue() { - return inValue; - } - - public double getOutTicks() { - return outTicks; - } - - public double getOutValue() { - return outValue; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 59 * hash - + (int) (Double.doubleToLongBits(this.inValue) - ^ (Double.doubleToLongBits(this.inValue) >>> 32)); - hash = 59 * hash - + (int) (Double.doubleToLongBits(this.outValue) - ^ (Double.doubleToLongBits(this.outValue) >>> 32)); - hash = 59 * hash + (int) (this.inTicks ^ (this.inTicks >>> 32)); - hash = 59 * hash + (int) (this.outTicks ^ (this.outTicks >>> 32)); - return hash; - } - - @Override - public String toString() { - return "NumberTangentInterpolator [inValue=" + inValue + ", inDuration=" - + TickCalculation.toDuration(inTicks) + ", outValue=" + outValue - + ", outDuration=" + TickCalculation.toDuration(outTicks) + "]"; - } - - @Override - protected double curve(double t) { - // Fallback: If NumberTangentInterpolator is used with a target, that is - // not a number, - // it behaves like linear interpolation. - return t; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/animation/SplineInterpolator.java b/gui/src/main/java/com/javafx/experiments/utils3d/animation/SplineInterpolator.java deleted file mode 100644 index d5b4a8b..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/animation/SplineInterpolator.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.animation; - -import javafx.animation.Interpolator; - -/** - * An implementation of a spline interpolator for temporal interpolation that - * tries to follow the specification referenced by: - * http://www.w3.org/TR/SMIL/animation.html#animationNS-OverviewSpline . - *

- * Basically, a cubic Bezier curve is created with start point (0,0) and - * endpoint (1,1). The other two control points (px1, py1) and (px2, py2) are - * given by the user, where px1, py1, px1, and px2 are all in the range [0,1]. A - * property of this specially constrained Bezier curve is that it is strictly - * monotonically increasing in both X and Y with t in range [0,1]. - *

- * The interpolator works by giving it a value for X. It then finds what - * parameter t would generate this X value for the curve. Then this t parameter - * is applied to the curve to solve for Y. As X increases from 0 to 1, t also - * increases from 0 to 1, and correspondingly Y increases from 0 to 1. The - * X-to-Y mapping is not a function of path/curve length. - */ -public class SplineInterpolator extends Interpolator { - - /** - * Power of 2 sample size for lookup table of x values. - */ - private static final int SAMPLE_SIZE = 16; - - /** - * Difference in t used to calculate each of the xSamples values -- power of - * 2 sample size should provide exact representation of this value and its - * integer multiples (integer in range of [0..SAMPLE_SIZE]. - */ - private static final double SAMPLE_INCREMENT = 1.0 / SAMPLE_SIZE; - - /** - * Do the input control points form a line with (0,0) and (1,1), i.e., x1 == - * y1 and x2 == y2 -- if so, then all x(t) == y(t) for the curve. - */ - private final boolean isCurveLinear; - - /** - * The coordinates of the 2 2D control points for a cubic Bezier curve, with - * implicit start point (0,0) and end point (1,1) -- each individual - * coordinate value must be in range [0,1]. - */ - private final double x1, y1, x2, y2; - - /** - * X values for the bezier curve, sampled at increments of 1/SAMPLE_SIZE -- - * this is used to find the good initial guess for parameter t, given an x. - */ - private final double[] xSamples = new double[SAMPLE_SIZE + 1]; - - /** - * Creates a new instance with control points (0,0) (px1,py1) (px2,py2) - * (1,1) -- px1, py1, px2, py2 all in range [0,1]. - * - * @param px1 - * X coordinate of first control point, in range [0,1] - * @param py1 - * Y coordinate of first control point, in range [0,1] - * @param px2 - * X coordinate of second control point, in range [0,1] - * @param py2 - * Y coordinate of second control point, in range [0,1] - */ - public SplineInterpolator(double px1, double py1, double px2, double py2) { - // check user input for precondition - if (px1 < 0 || px1 > 1 || py1 < 0 || py1 > 1 || px2 < 0 || px2 > 1 - || py2 < 0 || py2 > 1) { - throw new IllegalArgumentException("Control point coordinates must " - + "all be in range [0,1]"); - } - - // save control point data - this.x1 = px1; - this.y1 = py1; - this.x2 = px2; - this.y2 = py2; - - // calc linearity/identity curve - isCurveLinear = ((x1 == y1) && (x2 == y2)); - - // make the array of x value samples - if (!isCurveLinear) { - for (int i = 0; i < SAMPLE_SIZE + 1; ++i) { - xSamples[i] = eval(i * SAMPLE_INCREMENT, x1, x2); - } - } - } - - /** - * Returns the y-value of the cubic bezier curve that corresponds to the x - * input. - * - * @param x - * is x-value of cubic bezier curve, in range [0,1] - * @return corresponding y-value of cubic bezier curve -- in range [0,1] - */ - @Override - public double curve(double x) { - // check user input for precondition - if (x < 0 || x > 1) { - throw new IllegalArgumentException("x must be in range [0,1]"); - } - - // check quick exit identity cases (linear curve or curve endpoints) - if (isCurveLinear || x == 0 || x == 1) { - return x; - } - - // find the t parameter for a given x value, and use this t to calculate - // the corresponding y value - return eval(findTForX(x), y1, y2); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final SplineInterpolator other = (SplineInterpolator) obj; - if (Double.doubleToLongBits(this.x1) != Double.doubleToLongBits(other.x1)) { - return false; - } - if (Double.doubleToLongBits(this.y1) != Double.doubleToLongBits(other.y1)) { - return false; - } - if (Double.doubleToLongBits(this.x2) != Double.doubleToLongBits(other.x2)) { - return false; - } - if (Double.doubleToLongBits(this.y2) != Double.doubleToLongBits(other.y2)) { - return false; - } - return true; - } - - public double getX1() { - return x1; - } - - public double getX2() { - return x2; - } - - public double getY1() { - return y1; - } - - public double getY2() { - return y2; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 19 * hash + (int) (Double.doubleToLongBits(this.x1) - ^ (Double.doubleToLongBits(this.x1) >>> 32)); - hash = 19 * hash + (int) (Double.doubleToLongBits(this.y1) - ^ (Double.doubleToLongBits(this.y1) >>> 32)); - hash = 19 * hash + (int) (Double.doubleToLongBits(this.x2) - ^ (Double.doubleToLongBits(this.x2) >>> 32)); - hash = 19 * hash + (int) (Double.doubleToLongBits(this.y2) - ^ (Double.doubleToLongBits(this.y2) >>> 32)); - return hash; - } - - @Override - public String toString() { - return "SplineInterpolator [x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 - + ", y2=" + y2 + "]"; - } - - /** - * Use Bernstein basis to evaluate 1D cubic Bezier curve (quicker and more - * numerically stable than power basis) -- 1D control coordinates are (0, - * p1, p2, 1), where p1 and p2 are in range [0,1], and there is no ordering - * constraint on p1 and p2, i.e., p1 <= p2 does not have to be true. - * - * @param t - * is the paramaterized value in range [0,1] - * @param p1 - * is 1st control point coordinate in range [0,1] - * @param p2 - * is 2nd control point coordinate in range [0,1] - * @return the value of the Bezier curve at parameter t - */ - private double eval(double t, double p1, double p2) { - // Use optimized version of the normal Bernstein basis form of Bezier: - // (3*(1-t)*(1-t)*t*p1)+(3*(1-t)*t*t*p2)+(t*t*t), since p0=0, p3=1. - // The above unoptimized version is best using -server, but since we - // are probably doing client-side animation, this is faster. - double compT = 1 - t; - return t * (3 * compT * (compT * p1 + t * p2) + (t * t)); - } - - /** - * Evaluates Bernstein basis derivative of 1D cubic Bezier curve, where 1D - * control points are (0, p1, p2, 1), where p1 and p2 are in range [0,1], - * and there is no ordering constraint on p1 and p2, i.e., p1 <= p2 does - * not have to be true. - * - * @param t - * is the paramaterized value in range [0,1] - * @param p1 - * is 1st control point coordinate in range [0,1] - * @param p2 - * is 2nd control point coordinate in range [0,1] - * @return the value of the Bezier curve at parameter t - */ - private double evalDerivative(double t, double p1, double p2) { - // use optimized version of Berstein basis Bezier derivative: - // (3*(1-t)*(1-t)*p1)+(6*(1-t)*t*(p2-p1))+(3*t*t*(1-p2)), since - // p0=0 and p3=1. The above unoptimized version is best using -server, - // but since we are probably doing client-side animation, this is - // faster. - double compT = 1 - t; - return 3 - * (compT * (compT * p1 + 2 * t * (p2 - p1)) + t * t * (1 - p2)); - } - - /** - * Finds the parameter t that produces the given x-value for the curve -- - * uses Newton-Raphson to refine the value as opposed to subdividing until - * we are within some tolerance. - * - * @param x - * is x-value of cubic bezier curve, in range [0,1] - * @return the parameter t (in range [0,1]) that produces x - */ - private double findTForX(double x) { - // get an initial good guess for t - double t = getInitialGuessForT(x); - - // use Newton-Raphson to refine the value for t -- for this constrained - // Bezier with float accuracy (7 digits), any value not converged by 4 - // iterations is cycling between values, which can minutely affect the - // accuracy of the last digit - final int numIterations = 4; - for (int i = 0; i < numIterations; ++i) { - // stop if this value of t gives us exactly x - double xT = (eval(t, x1, x2) - x); - if (xT == 0) { - break; - } - - // stop if derivative is 0 - double dXdT = evalDerivative(t, x1, x2); - if (dXdT == 0) { - break; - } - - // refine t - t -= xT / dXdT; - } - - return t; - } - - /** - * Find an initial good guess for what parameter t might produce the x-value - * on the Bezier curve -- uses linear interpolation on the x-value sample - * array that was created on construction. - * - * @param x - * is x-value of cubic bezier curve, in range [0,1] - * @return a good initial guess for parameter t (in range [0,1]) that gives - * x - */ - private double getInitialGuessForT(double x) { - // find which places in the array that x would be sandwiched between, - // and then linearly interpolate a reasonable value of t -- array values - // are ascending (or at least never descending) -- binary search is - // probably more trouble than it is worth here - for (int i = 1; i < SAMPLE_SIZE + 1; ++i) { - if (xSamples[i] >= x) { - double xRange = xSamples[i] - xSamples[i - 1]; - if (xRange == 0) { - // no change in value between samples, so use earlier time - return (i - 1) * SAMPLE_INCREMENT; - } else { - // linearly interpolate the time value - return ((i - 1) + ((x - xSamples[i - 1]) / xRange)) - * SAMPLE_INCREMENT; - } - } - } - - // shouldn't get here since 0 <= x <= 1, and xSamples[0] == 0 and - // xSamples[SAMPLE_SIZE] == 1 (using power of 2 SAMPLE_SIZE for more - // exact increment arithmetic) - return 1; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/animation/TickCalculation.java b/gui/src/main/java/com/javafx/experiments/utils3d/animation/TickCalculation.java deleted file mode 100644 index c512633..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/animation/TickCalculation.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.animation; - -import javafx.util.Duration; - -public class TickCalculation { - public static final int TICKS_PER_SECOND = 6000; - private static final double TICKS_PER_MILI = TICKS_PER_SECOND / 1000.0; - private static final double TICKS_PER_NANO = TICKS_PER_MILI * 1e-6; - - public static long add(long op1, long op2) { - assert (op1 >= 0); - - if (op1 == Long.MAX_VALUE || op2 == Long.MAX_VALUE) { - return Long.MAX_VALUE; - } else if (op2 == Long.MIN_VALUE) { - return 0; - } - - if (op2 >= 0) { - final long result = op1 + op2; - return (result < 0) ? Long.MAX_VALUE : result; - } else { - return Math.max(0, op1 + op2); - } - - } - - public static long fromDuration(Duration duration) { - return fromMillis(duration.toMillis()); - } - - public static long fromDuration(Duration duration, double rate) { - return Math.round(TICKS_PER_MILI * duration.toMillis() - / Math.abs(rate)); - } - - public static long fromMillis(double millis) { - return Math.round(TICKS_PER_MILI * millis); - } - - public static long fromNano(long nano) { - return Math.round(TICKS_PER_NANO * nano); - } - - public static long sub(long op1, long op2) { - assert (op1 >= 0); - - if (op1 == Long.MAX_VALUE || op2 == Long.MIN_VALUE) { - return Long.MAX_VALUE; - } else if (op2 == Long.MAX_VALUE) { - return 0; - } - - if (op2 >= 0) { - return Math.max(0, op1 - op2); - } else { - final long result = op1 - op2; - return result < 0 ? Long.MAX_VALUE : result; - } - - } - - public static Duration toDuration(long ticks) { - return Duration.millis(toMillis(ticks)); - } - - public static double toMillis(long ticks) { - return ticks / TICKS_PER_MILI; - } - - private TickCalculation() { - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/BaseBounds.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/BaseBounds.java deleted file mode 100644 index cdf56ea..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/BaseBounds.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * Base class for mutable bounds objects. There are two concrete - * specializations, BoxBounds (3D) and RectBounds (2D). Various "derive" methods - * exist which are used to mutate the bounds objects, such that they can be - * converted between the different types as appropriate, or modified in place if - * possible. This allows us to churn memory as little as possible without - * representing everything as if it were in 3D space (there are some - * computational cost savings to being able to ignore the Z values). - */ -public abstract class BaseBounds { - - /** - * The different types of BaseBounds that are currently supported. We might - * support other types of bounds in the future (such as SPHERE) which are - * also 2D or 3D but are defined in some way other than with a bounding box. - * Such bounds can sometimes more accurately represent the pixels - */ - public static enum BoundsType { - BOX, // A 2D axis-aligned bounding rectangle - RECTANGLE, // A 3D axis-aligned bounding box - } - - public static BaseBounds getInstance(float minX, float minY, float maxX, - float maxY) { - return new RectBounds(minX, minY, maxX, maxY); - } - - public static BaseBounds getInstance(float minX, float minY, float minZ, - float maxX, float maxY, float maxZ) { - if (minZ == 0 && maxZ == 0) { - return getInstance(minX, minY, maxX, maxY); - } else { - return new BoxBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - } - - // Only allow subclasses in this package - BaseBounds() { - } - - public abstract void add(float x, float y, float z); - - // TODO: obsolete add and replace with deriveWithUnion(Vec2f v) and deriveWithUnion(Vec3f v) - // (RT-26886) - public abstract void add(Point2D p); - - public abstract boolean contains(float x, float y); - - public abstract boolean contains(Point2D p); - - /** - * Duplicates this instance. This differs from deriveWithNewBounds(other) - * where "other" would be this, in that derive methods may return the same - * instance, whereas copy will always return a new instance. - */ - public abstract BaseBounds copy(); - - public abstract BaseBounds deriveWithNewBounds(BaseBounds other); - - public abstract BaseBounds deriveWithNewBounds(float minX, float minY, - float minZ, float maxX, - float maxY, float maxZ); - - // TODO: Add variants of deriveWithNewBounds such as pair of Vec* (RT-26886) - public abstract BaseBounds deriveWithNewBounds(Rectangle other); - - public abstract BaseBounds deriveWithNewBoundsAndSort(float minX, - float minY, - float minZ, - float maxX, - float maxY, - float maxZ); - - public abstract BaseBounds deriveWithPadding(float h, float v, float d); - - public abstract BaseBounds deriveWithUnion(BaseBounds other); - - public abstract boolean disjoint(float x, float y, float width, - float height); - - /** - * Sets the given RectBounds (or creates a new instance of bounds is null) - * to have the minX, minY, maxX, and maxY of this BoxBounds, dropping the Z - * values. - * - * @param bounds - * The bounds to fill with values, or null. If null, a new - * RectBounds is returned. If not null, the given bounds will be - * populated and then returned - * @return a non-null reference to a RectBounds containing the minX, minY, - * maxX, and maxY of this BoxBounds. - */ - public abstract RectBounds flattenInto(RectBounds bounds); - - public abstract BoundsType getBoundsType(); - - /** - * Convenience function for getting the depth of this bounds. The dimension - * along the Z-Axis. - */ - public abstract float getDepth(); - - /** - * Convenience function for getting the height of this bounds. The dimension - * along the Y-Axis. - */ - public abstract float getHeight(); - - public abstract Vec2f getMax(Vec2f max); - - public abstract Vec3f getMax(Vec3f max); - - public abstract float getMaxX(); - - public abstract float getMaxY(); - - public abstract float getMaxZ(); - - public abstract Vec2f getMin(Vec2f min); - - public abstract Vec3f getMin(Vec3f min); - - public abstract float getMinX(); - - public abstract float getMinY(); - - public abstract float getMinZ(); - - /** - * Convenience function for getting the width of this bounds. The dimension - * along the X-Axis. - */ - public abstract float getWidth(); - - public abstract boolean intersects(float x, float y, float width, - float height); - - public abstract void intersectWith(BaseBounds other); - - public abstract void intersectWith(float minX, float minY, float minZ, - float maxX, float maxY, float maxZ); - - public abstract void intersectWith(Rectangle other); - - /** - * Return true if this bounds is of a 2D BoundsType, else false. - */ - public abstract boolean is2D(); - - public abstract boolean isEmpty(); - - public abstract BaseBounds makeEmpty(); - - public abstract void roundOut(); - - public abstract void setBoundsAndSort(float minX, float minY, float minZ, - float maxX, float maxY, float maxZ); - - /** - * Sets the bounds based on the given points, and also ensures that after - * having done so that this bounds instance is sorted (x1<=x2 and y1<=y2). - */ - public abstract void setBoundsAndSort(Point2D p1, Point2D p2); - - public abstract void translate(float x, float y, float z); - - protected abstract void sortMinMax(); -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/BoxBounds.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/BoxBounds.java deleted file mode 100644 index 7ef2c2d..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/BoxBounds.java +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -public class BoxBounds extends BaseBounds { - // maximum x value of boundining box - private float maxX; - // maximum y value of boundining box - private float maxY; - // maximum z value of boundining box - private float maxZ; - // minimum x value of boundining box - private float minX; - // minimum y value of boundining box - private float minY; - // minimum z value of boundining box - private float minZ; - - /** - * Create an axis aligned bounding box object, with an empty bounds where - * maxX < minX, maxY < minY and maxZ < minZ. - */ - public BoxBounds() { - minX = minY = minZ = 0.0f; - maxX = maxY = maxZ = -1.0f; - } - - /** - * Creates an axis aligned bounding box as a copy of the specified BoxBounds - * object. - */ - public BoxBounds(BoxBounds other) { - setBounds(other); - } - - /** - * Creates an axis aligned bounding box based on the minX, minY, minZ, maxX, - * maxY, and maxZ values specified. - */ - public BoxBounds(float minX, float minY, float minZ, float maxX, float maxY, - float maxZ) { - setBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public void add(float x, float y, float z) { - unionWith(x, y, z, x, y, z); - } - - @Override - public void add(Point2D p) { - add(p.x, p.y, 0.0f); - } - - @Override - public boolean contains(float x, float y) { - if (isEmpty()) { - return false; - } - return contains(x, y, 0.0f); - } - - public boolean contains(float x, float y, float z) { - if (isEmpty()) { - return false; - } - return (x >= minX && x <= maxX && y >= minY && y <= maxY && z >= minZ - && z <= maxZ); - } - - public boolean contains(float x, float y, float z, float width, - float height, float depth) { - if (isEmpty()) { - return false; - } - return contains(x, y, z) && contains(x + width, y + height, z + depth); - } - - @Override - public boolean contains(Point2D p) { - if ((p == null) || isEmpty()) { - return false; - } - return contains(p.x, p.y, 0.0f); - } - - @Override - public BaseBounds copy() { - return new BoxBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public BaseBounds deriveWithNewBounds(BaseBounds other) { - if (other.isEmpty()) { - return makeEmpty(); - } - if ((other.getBoundsType() == BoundsType.RECTANGLE) - || (other.getBoundsType() == BoundsType.BOX)) { - minX = other.getMinX(); - minY = other.getMinY(); - minZ = other.getMinZ(); - maxX = other.getMaxX(); - maxY = other.getMaxY(); - maxZ = other.getMaxZ(); - } else { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - return this; - } - - @Override - public BaseBounds deriveWithNewBounds(float minX, float minY, float minZ, - float maxX, float maxY, float maxZ) { - if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) { - return makeEmpty(); - } - this.minX = minX; - this.minY = minY; - this.minZ = minZ; - this.maxX = maxX; - this.maxY = maxY; - this.maxZ = maxZ; - return this; - } - - @Override - public BaseBounds deriveWithNewBounds(Rectangle other) { - if (other.width < 0 || other.height < 0) { - return makeEmpty(); - } - setBounds(other.x, other.y, 0, other.x + other.width, - other.y + other.height, 0); - return this; - } - - @Override - public BaseBounds deriveWithNewBoundsAndSort(float minX, float minY, - float minZ, float maxX, - float maxY, float maxZ) { - setBoundsAndSort(minX, minY, minZ, maxX, maxY, maxZ); - return this; - } - - @Override - public BaseBounds deriveWithPadding(float h, float v, float d) { - grow(h, v, d); - return this; - } - - @Override - public BaseBounds deriveWithUnion(BaseBounds other) { - if ((other.getBoundsType() == BoundsType.RECTANGLE) - || (other.getBoundsType() == BoundsType.BOX)) { - unionWith(other); - } else { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - return this; - } - - @Override - public boolean disjoint(float x, float y, float width, float height) { - return disjoint(x, y, 0f, width, height, 0f); - } - - public boolean disjoint(float x, float y, float z, float width, - float height, float depth) { - if (isEmpty()) { - return true; - } - return (x + width < minX || y + height < minY || z + depth < minZ - || x > maxX || y > maxY || z > maxZ); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - - final BoxBounds other = (BoxBounds) obj; - if (minX != other.getMinX()) { - return false; - } - if (minY != other.getMinY()) { - return false; - } - if (minZ != other.getMinZ()) { - return false; - } - if (maxX != other.getMaxX()) { - return false; - } - if (maxY != other.getMaxY()) { - return false; - } - if (maxZ != other.getMaxZ()) { - return false; - } - return true; - } - - @Override - public RectBounds flattenInto(RectBounds bounds) { - // Create the bounds if we need to - if (bounds == null) { - bounds = new RectBounds(); - } - // Make it empty if we need to - if (isEmpty()) { - return bounds.makeEmpty(); - } - // Populate it with values otherwise - bounds.setBounds(minX, minY, maxX, maxY); - return bounds; - } - - @Override - public BoundsType getBoundsType() { - return BoundsType.BOX; - } - - /** - * Convenience function for getting the depth of this bounds. The dimension - * along the Z-Axis. - */ - @Override - public float getDepth() { - return maxZ - minZ; - } - - /** - * Convenience function for getting the height of this bounds. The dimension - * along the Y-Axis. - */ - @Override - public float getHeight() { - return maxY - minY; - } - - @Override - public Vec2f getMax(Vec2f max) { - if (max == null) { - max = new Vec2f(); - } - max.x = maxX; - max.y = maxY; - return max; - } - - @Override - public Vec3f getMax(Vec3f max) { - if (max == null) { - max = new Vec3f(); - } - max.x = maxX; - max.y = maxY; - max.z = maxZ; - return max; - - } - - @Override - public float getMaxX() { - return maxX; - } - - @Override - public float getMaxY() { - return maxY; - } - - @Override - public float getMaxZ() { - return maxZ; - } - - @Override - public Vec2f getMin(Vec2f min) { - if (min == null) { - min = new Vec2f(); - } - min.x = minX; - min.y = minY; - return min; - } - - @Override - public Vec3f getMin(Vec3f min) { - if (min == null) { - min = new Vec3f(); - } - min.x = minX; - min.y = minY; - min.z = minZ; - return min; - - } - - @Override - public float getMinX() { - return minX; - } - - @Override - public float getMinY() { - return minY; - } - - @Override - public float getMinZ() { - return minZ; - } - - /** - * Convenience function for getting the width of this bounds. The dimension - * along the X-Axis. - */ - @Override - public float getWidth() { - return maxX - minX; - } - - public void grow(float h, float v, float d) { - minX -= h; - maxX += h; - minY -= v; - maxY += v; - minZ -= d; - maxZ += d; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 79 * hash + Float.floatToIntBits(minX); - hash = 79 * hash + Float.floatToIntBits(minY); - hash = 79 * hash + Float.floatToIntBits(minZ); - hash = 79 * hash + Float.floatToIntBits(maxX); - hash = 79 * hash + Float.floatToIntBits(maxY); - hash = 79 * hash + Float.floatToIntBits(maxZ); - - return hash; - } - - public boolean intersects(BaseBounds other) { - if ((other == null) || other.isEmpty() || isEmpty()) { - return false; - } - return (other.getMaxX() >= minX && other.getMaxY() >= minY - && other.getMaxZ() >= minZ && other.getMinX() <= maxX - && other.getMinY() <= maxY && other.getMinZ() <= maxZ); - } - - @Override - public boolean intersects(float x, float y, float width, float height) { - return intersects(x, y, 0.0f, width, height, 0.0f); - } - - public boolean intersects(float x, float y, float z, float width, - float height, float depth) { - if (isEmpty()) { - return false; - } - return (x + width >= minX && y + height >= minY && z + depth >= minZ - && x <= maxX && y <= maxY && z <= maxZ); - } - - @Override - public void intersectWith(BaseBounds other) { - // Short circuit intersect if either bounds is empty. - if (this.isEmpty()) { - return; - } - if (other.isEmpty()) { - makeEmpty(); - return; - } - - minX = Math.max(minX, other.getMinX()); - minY = Math.max(minY, other.getMinY()); - minZ = Math.max(minZ, other.getMinZ()); - maxX = Math.min(maxX, other.getMaxX()); - maxY = Math.min(maxY, other.getMaxY()); - maxZ = Math.min(maxZ, other.getMaxZ()); - } - - @Override - public void intersectWith(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - // Short circuit intersect if either bounds is empty. - if (this.isEmpty()) { - return; - } - if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) { - makeEmpty(); - return; - } - - this.minX = Math.max(this.minX, minX); - this.minY = Math.max(this.minY, minY); - this.minZ = Math.max(this.minZ, minZ); - this.maxX = Math.min(this.maxX, maxX); - this.maxY = Math.min(this.maxY, maxY); - this.maxZ = Math.min(this.maxZ, maxZ); - } - - @Override - public void intersectWith(Rectangle other) { - float x = other.x; - float y = other.y; - intersectWith(x, y, 0, x + other.width, y + other.height, 0); - } - - @Override - public boolean is2D() { - return false; - } - - @Override - public boolean isEmpty() { - return maxX < minX || maxY < minY || maxZ < minZ; - } - - // for convenience, this function returns a reference to itself, so we can - // change from using "bounds.makeEmpty(); return bounds;" to just - // "return bounds.makeEmpty()" - @Override - public BoxBounds makeEmpty() { - minX = minY = minZ = 0.0f; - maxX = maxY = maxZ = -1.0f; - return this; - } - - /** - * Adjusts the edges of this BoxBounds "outward" toward integral boundaries, - * such that the rounded bounding box will always full enclose the original - * bounding box. - */ - @Override - public void roundOut() { - minX = (float) Math.floor(minX); - minY = (float) Math.floor(minY); - minZ = (float) Math.floor(minZ); - maxX = (float) Math.ceil(maxX); - maxY = (float) Math.ceil(maxY); - maxZ = (float) Math.ceil(maxZ); - } - - /** - * Set the bounds to match that of the BaseBounds object specified. The - * specified bounds object must not be null. - */ - public final void setBounds(BaseBounds other) { - minX = other.getMinX(); - minY = other.getMinY(); - minZ = other.getMinZ(); - maxX = other.getMaxX(); - maxY = other.getMaxY(); - maxZ = other.getMaxZ(); - } - - /** - * Set the bounds to the given values. - */ - public final void setBounds(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - this.minX = minX; - this.minY = minY; - this.minZ = minZ; - this.maxX = maxX; - this.maxY = maxY; - this.maxZ = maxZ; - } - - @Override - public void setBoundsAndSort(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - setBounds(minX, minY, minZ, maxX, maxY, maxZ); - sortMinMax(); - } - - @Override - public void setBoundsAndSort(Point2D p1, Point2D p2) { - setBoundsAndSort(p1.x, p1.y, 0.0f, p2.x, p2.y, 0.0f); - } - - public void setMaxX(float maxX) { - this.maxX = maxX; - } - - public void setMaxY(float maxY) { - this.maxY = maxY; - } - - public void setMaxZ(float maxZ) { - this.maxZ = maxZ; - } - - public void setMinX(float minX) { - this.minX = minX; - } - - public void setMinY(float minY) { - this.minY = minY; - } - - public void setMinZ(float minZ) { - this.minZ = minZ; - } - - @Override - public String toString() { - return "BoxBounds { minX:" + minX + ", minY:" + minY + ", minZ:" + minZ - + ", maxX:" + maxX + ", maxY:" + maxY + ", maxZ:" + maxZ + "}"; - } - - @Override - public void translate(float x, float y, float z) { - setMinX(getMinX() + x); - setMinY(getMinY() + y); - setMaxX(getMaxX() + x); - setMaxY(getMaxY() + y); - } - - public void unionWith(BaseBounds other) { - // Short circuit union if either bounds is empty. - if (other.isEmpty()) { - return; - } - if (this.isEmpty()) { - setBounds(other); - return; - } - - minX = Math.min(minX, other.getMinX()); - minY = Math.min(minY, other.getMinY()); - minZ = Math.min(minZ, other.getMinZ()); - maxX = Math.max(maxX, other.getMaxX()); - maxY = Math.max(maxY, other.getMaxY()); - maxZ = Math.max(maxZ, other.getMaxZ()); - } - - public void unionWith(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - // Short circuit union if either bounds is empty. - if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) { - return; - } - if (this.isEmpty()) { - setBounds(minX, minY, minZ, maxX, maxY, maxZ); - return; - } - - this.minX = Math.min(this.minX, minX); - this.minY = Math.min(this.minY, minY); - this.minZ = Math.min(this.minZ, minZ); - this.maxX = Math.max(this.maxX, maxX); - this.maxY = Math.max(this.maxY, maxY); - this.maxZ = Math.max(this.maxZ, maxZ); - } - - @Override - protected void sortMinMax() { - if (minX > maxX) { - float tmp = maxX; - maxX = minX; - minX = tmp; - } - if (minY > maxY) { - float tmp = maxY; - maxY = minY; - minY = tmp; - } - if (minZ > maxZ) { - float tmp = maxZ; - maxZ = minZ; - minZ = tmp; - } - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Dimension2D.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Dimension2D.java deleted file mode 100644 index 29d2d5f..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Dimension2D.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * The Dimension2D class is to encapsulate a width and a height - * dimension. - *

- */ -public class Dimension2D { - public float height; - public float width; - - public Dimension2D() { - } - - public Dimension2D(float w, float h) { - width = w; - height = h; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Point2D.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Point2D.java deleted file mode 100644 index a1b346b..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Point2D.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * The Point2D class defines a point representing a location in - * {@code (x, y)} coordinate space. - *

- */ -public class Point2D { - /** - * Returns the distance between two points. - * - * @param x1 - * the X coordinate of the first specified point - * @param y1 - * the Y coordinate of the first specified point - * @param x2 - * the X coordinate of the second specified point - * @param y2 - * the Y coordinate of the second specified point - * @return the distance between the two sets of specified coordinates. - */ - public static float distance(float x1, float y1, float x2, float y2) { - x1 -= x2; - y1 -= y2; - return (float) Math.sqrt(x1 * x1 + y1 * y1); - } - - /** - * Returns the square of the distance between two points. - * - * @param x1 - * the X coordinate of the first specified point - * @param y1 - * the Y coordinate of the first specified point - * @param x2 - * the X coordinate of the second specified point - * @param y2 - * the Y coordinate of the second specified point - * @return the square of the distance between the two sets of specified - * coordinates. - */ - public static float distanceSq(float x1, float y1, float x2, float y2) { - x1 -= x2; - y1 -= y2; - return (x1 * x1 + y1 * y1); - } - - /** - * The X coordinate of this Point2D. - */ - public float x; - - /** - * The Y coordinate of this Point2D. - */ - public float y; - - /** - * Constructs and initializes a Point2D with coordinates - * (0, 0). - */ - public Point2D() { - } - - /** - * Constructs and initializes a Point2D with the specified - * coordinates. - * - * @param x - * the X coordinate of the newly constructed Point2D - * @param y - * the Y coordinate of the newly constructed Point2D - */ - public Point2D(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Returns the distance from this Point2D to a specified point. - * - * @param px - * the X coordinate of the specified point to be measured against - * this Point2D - * @param py - * the Y coordinate of the specified point to be measured against - * this Point2D - * @return the distance between this Point2D and a specified - * point. - */ - public float distance(float px, float py) { - px -= x; - py -= y; - return (float) Math.sqrt(px * px + py * py); - } - - /** - * Returns the distance from this Point2D to a specified - * Point2D. - * - * @param pt - * the specified point to be measured against this - * Point2D - * @return the distance between this Point2D and the specified - * Point2D. - */ - public float distance(Point2D pt) { - float px = pt.x - this.x; - float py = pt.y - this.y; - return (float) Math.sqrt(px * px + py * py); - } - - /** - * Returns the square of the distance from this Point2D to a - * specified point. - * - * @param px - * the X coordinate of the specified point to be measured against - * this Point2D - * @param py - * the Y coordinate of the specified point to be measured against - * this Point2D - * @return the square of the distance between this Point2D and - * the specified point. - */ - public float distanceSq(float px, float py) { - px -= x; - py -= y; - return (px * px + py * py); - } - - /** - * Returns the square of the distance from this Point2D to a - * specified Point2D. - * - * @param pt - * the specified point to be measured against this - * Point2D - * @return the square of the distance between this Point2D to a - * specified Point2D. - */ - public float distanceSq(Point2D pt) { - float px = pt.x - this.x; - float py = pt.y - this.y; - return (px * px + py * py); - } - - /** - * Determines whether or not two points are equal. Two instances of - * Point2D are equal if the values of their x and - * y member fields, representing their position in the - * coordinate space, are the same. - * - * @param obj - * an object to be compared with this Point2D - * @return true if the object to be compared is an instance of - * Point2D and has the same values; false - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Point2D) { - Point2D p2d = (Point2D) obj; - return (x == p2d.x) && (y == p2d.y); - } - return false; - } - - /** - * Returns the hashcode for this Point2D. - * - * @return a hash code for this Point2D. - */ - @Override - public int hashCode() { - int bits = Float.floatToIntBits(x); - bits ^= Float.floatToIntBits(y) * 31; - return bits; - } - - /** - * Sets the location of this Point2D to the specified - * float coordinates. - * - * @param x - * the new X coordinate of this {@code Point2D} - * @param y - * the new Y coordinate of this {@code Point2D} - */ - public void setLocation(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Sets the location of this Point2D to the same coordinates as - * the specified Point2D object. - * - * @param p - * the specified Point2D to which to set this - * Point2D - */ - public void setLocation(Point2D p) { - setLocation(p.x, p.y); - } - - /** - * Returns a String that represents the value of this - * Point2D. - * - * @return a string representation of this Point2D. - */ - @Override - public String toString() { - return "Point2D[" + x + ", " + y + "]"; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/RectBounds.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/RectBounds.java deleted file mode 100644 index 55c4d00..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/RectBounds.java +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * A simple object which carries bounds information as floats, and has no Z - * components. - */ -public final class RectBounds extends BaseBounds { - // maximum x value of bounding box - private float maxX; - // maximum y value of bounding box - private float maxY; - // minimum x value of bounding box - private float minX; - // minimum y value of bounding box - private float minY; - - /** - * Create an axis aligned bounding rectangle object, with an empty bounds - * where maxX < minX and maxY < minY. - */ - public RectBounds() { - minX = minY = 0.0f; - maxX = maxY = -1.0f; - } - - /** - * Creates a RectBounds based on the minX, minY, maxX, and maxY values - * specified. - */ - public RectBounds(float minX, float minY, float maxX, float maxY) { - setBounds(minX, minY, maxX, maxY); - } - - /** - * Creates a RectBounds object as a copy of the specified RECTANGLE. - */ - public RectBounds(Rectangle other) { - setBounds(other.x, other.y, other.x + other.width, - other.y + other.height); - } - - /** - * Creates a RectBounds object as a copy of the specified RectBounds object. - */ - public RectBounds(RectBounds other) { - setBounds(other); - } - - public void add(float x, float y) { - unionWith(x, y, x, y); - } - - @Override - public void add(float x, float y, float z) { - if (z != 0) { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - unionWith(x, y, x, y); - } - - @Override - public void add(Point2D p) { - add(p.x, p.y); - } - - @Override - public boolean contains(float x, float y) { - if (isEmpty()) { - return false; - } - return (x >= minX && x <= maxX && y >= minY && y <= maxY); - } - - @Override - public boolean contains(Point2D p) { - if ((p == null) || isEmpty()) { - return false; - } - return (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY); - } - - /** - * Determines whether the given other RectBounds is completely - * contained within this RectBounds. Equivalent RectBounds will return true. - * - * @param other - * The other rect bounds to check against. - * @return Whether the other rect bounds is contained within this one, which - * also includes equivalence. - */ - public boolean contains(RectBounds other) { - if (isEmpty() || other.isEmpty()) { - return false; - } - return minX <= other.minX && maxX >= other.maxX && minY <= other.minY - && maxY >= other.maxY; - } - - @Override - public BaseBounds copy() { - return new RectBounds(minX, minY, maxX, maxY); - } - - @Override - public BaseBounds deriveWithNewBounds(BaseBounds other) { - if (other.isEmpty()) { - return makeEmpty(); - } - if (other.getBoundsType() == BoundsType.RECTANGLE) { - RectBounds rb = (RectBounds) other; - minX = rb.getMinX(); - minY = rb.getMinY(); - maxX = rb.getMaxX(); - maxY = rb.getMaxY(); - } else if (other.getBoundsType() == BoundsType.BOX) { - return new BoxBounds((BoxBounds) other); - } else { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - return this; - } - - @Override - public BaseBounds deriveWithNewBounds(float minX, float minY, float minZ, - float maxX, float maxY, float maxZ) { - if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) { - return makeEmpty(); - } - if ((minZ == 0) && (maxZ == 0)) { - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - return this; - } - return new BoxBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public BaseBounds deriveWithNewBounds(Rectangle other) { - if (other.width < 0 || other.height < 0) { - return makeEmpty(); - } - setBounds(other.x, other.y, other.x + other.width, - other.y + other.height); - return this; - } - - @Override - public BaseBounds deriveWithNewBoundsAndSort(float minX, float minY, - float minZ, float maxX, - float maxY, float maxZ) { - if ((minZ == 0) && (maxZ == 0)) { - setBoundsAndSort(minX, minY, minZ, maxX, maxY, maxZ); - return this; - } - - BaseBounds bb = new BoxBounds(); - bb.setBoundsAndSort(minX, minY, minZ, maxX, maxY, maxZ); - return bb; - } - - @Override - public BaseBounds deriveWithPadding(float h, float v, float d) { - if (d == 0) { - grow(h, v); - return this; - } - BoxBounds bb = new BoxBounds(minX, minY, 0, maxX, maxY, 0); - bb.grow(h, v, d); - return bb; - } - - @Override - public BaseBounds deriveWithUnion(BaseBounds other) { - if (other.getBoundsType() == BoundsType.RECTANGLE) { - RectBounds rb = (RectBounds) other; - unionWith(rb); - } else if (other.getBoundsType() == BoundsType.BOX) { - BoxBounds bb = new BoxBounds((BoxBounds) other); - bb.unionWith(this); - return bb; - } else { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - return this; - } - - @Override - public boolean disjoint(float x, float y, float width, float height) { - if (isEmpty()) { - return true; - } - return (x + width < minX || y + height < minY || x > maxX || y > maxY); - } - - public boolean disjoint(RectBounds other) { - if ((other == null) || other.isEmpty() || isEmpty()) { - return true; - } - return (other.getMaxX() < minX || other.getMaxY() < minY - || other.getMinX() > maxX || other.getMinY() > maxY); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - - final RectBounds other = (RectBounds) obj; - if (minX != other.getMinX()) { - return false; - } - if (minY != other.getMinY()) { - return false; - } - if (maxX != other.getMaxX()) { - return false; - } - if (maxY != other.getMaxY()) { - return false; - } - return true; - } - - // Note: this implementation is exactly the same as BoxBounds. I could put a default - // implementation in BaseBounds which calls the getters, or I could move the minX, minY - // etc up to BaseBounds, or I could (maybe?) have BoxBounds extend from RectBounds or - // have both extend a common parent. In the end I wanted direct access to the fields - // but this was the only way to get it without making a more major change. - @Override - public RectBounds flattenInto(RectBounds bounds) { - // Create the bounds if we need to - if (bounds == null) { - bounds = new RectBounds(); - } - // Make it empty if we need to - if (isEmpty()) { - return bounds.makeEmpty(); - } - // Populate it with values otherwise - bounds.setBounds(minX, minY, maxX, maxY); - return bounds; - } - - @Override - public BoundsType getBoundsType() { - return BoundsType.RECTANGLE; - } - - /** - * Convenience function for getting the depth of this RectBounds The - * dimension along the Z-Axis, since this is a 2D bounds the return value is - * always 0.0f. - */ - @Override - public float getDepth() { - return 0.0f; - } - - /** - * Convenience function for getting the height of this RectBounds The - * dimension along the Y-Axis. - */ - @Override - public float getHeight() { - return maxY - minY; - } - - @Override - public Vec2f getMax(Vec2f max) { - if (max == null) { - max = new Vec2f(); - } - max.x = maxX; - max.y = maxY; - return max; - } - - @Override - public Vec3f getMax(Vec3f max) { - if (max == null) { - max = new Vec3f(); - } - max.x = maxX; - max.y = maxY; - max.z = 0.0f; - return max; - - } - - @Override - public float getMaxX() { - return maxX; - } - - @Override - public float getMaxY() { - return maxY; - } - - @Override - public float getMaxZ() { - return 0.0f; - } - - @Override - public Vec2f getMin(Vec2f min) { - if (min == null) { - min = new Vec2f(); - } - min.x = minX; - min.y = minY; - return min; - } - - @Override - public Vec3f getMin(Vec3f min) { - if (min == null) { - min = new Vec3f(); - } - min.x = minX; - min.y = minY; - min.z = 0.0f; - return min; - - } - - @Override - public float getMinX() { - return minX; - } - - @Override - public float getMinY() { - return minY; - } - - @Override - public float getMinZ() { - return 0.0f; - } - - /** - * Convenience function for getting the width of this RectBounds. The - * dimension along the X-Axis. - */ - @Override - public float getWidth() { - return maxX - minX; - } - - public void grow(float h, float v) { - minX -= h; - maxX += h; - minY -= v; - maxY += v; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 79 * hash + Float.floatToIntBits(minX); - hash = 79 * hash + Float.floatToIntBits(minY); - hash = 79 * hash + Float.floatToIntBits(maxX); - hash = 79 * hash + Float.floatToIntBits(maxY); - return hash; - } - - public boolean intersects(BaseBounds other) { - if ((other == null) || other.isEmpty() || isEmpty()) { - return false; - } - return (other.getMaxX() >= minX && other.getMaxY() >= minY - && other.getMaxZ() >= getMinZ() && other.getMinX() <= maxX - && other.getMinY() <= maxY && other.getMinZ() <= getMaxZ()); - } - - @Override - public boolean intersects(float x, float y, float width, float height) { - if (isEmpty()) { - return false; - } - return (x + width >= minX && y + height >= minY && x <= maxX - && y <= maxY); - } - - @Override - public void intersectWith(BaseBounds other) { - // Short circuit intersect if either bounds is empty. - if (this.isEmpty()) { - return; - } - if (other.isEmpty()) { - makeEmpty(); - return; - } - - minX = Math.max(minX, other.getMinX()); - minY = Math.max(minY, other.getMinY()); - maxX = Math.min(maxX, other.getMaxX()); - maxY = Math.min(maxY, other.getMaxY()); - } - - public void intersectWith(float minX, float minY, float maxX, float maxY) { - // Short circuit intersect if either bounds is empty. - if (this.isEmpty()) { - return; - } - if ((maxX < minX) || (maxY < minY)) { - makeEmpty(); - return; - } - - this.minX = Math.max(this.minX, minX); - this.minY = Math.max(this.minY, minY); - this.maxX = Math.min(this.maxX, maxX); - this.maxY = Math.min(this.maxY, maxY); - } - - @Override - public void intersectWith(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - // Short circuit intersect if either bounds is empty. - if (this.isEmpty()) { - return; - } - if ((maxX < minX) || (maxY < minY) || (maxZ < minZ)) { - makeEmpty(); - return; - } - - this.minX = Math.max(this.minX, minX); - this.minY = Math.max(this.minY, minY); - this.maxX = Math.min(this.maxX, maxX); - this.maxY = Math.min(this.maxY, maxY); - } - - @Override - public void intersectWith(Rectangle other) { - float x = other.x; - float y = other.y; - intersectWith(x, y, x + other.width, y + other.height); - } - - @Override - public boolean is2D() { - return true; - } - - @Override - public boolean isEmpty() { - // NaN values will cause the comparisons to fail and return "empty" - return !(maxX >= minX && maxY >= minY); - } - - // for convenience, this function returns a reference to itself, so we can - // change from using "bounds.makeEmpty(); return bounds;" to just - // "return bounds.makeEmpty()" - @Override - public RectBounds makeEmpty() { - minX = minY = 0.0f; - maxX = maxY = -1.0f; - return this; - } - - /** - * Adjusts the edges of this RectBounds "outward" toward integral - * boundaries, such that the rounded bounding box will always full enclose - * the original bounding box. - */ - @Override - public void roundOut() { - minX = (float) Math.floor(minX); - minY = (float) Math.floor(minY); - maxX = (float) Math.ceil(maxX); - maxY = (float) Math.ceil(maxY); - } - - /** - * Set the bounds to the given values. - */ - public final void setBounds(float minX, float minY, float maxX, - float maxY) { - this.minX = minX; - this.minY = minY; - this.maxX = maxX; - this.maxY = maxY; - } - - /** - * Set the bounds to match that of the RectBounds object specified. The - * specified bounds object must not be null. - */ - public final void setBounds(RectBounds other) { - minX = other.getMinX(); - minY = other.getMinY(); - maxX = other.getMaxX(); - maxY = other.getMaxY(); - } - - /** - * Sets the bounds based on the given coords, and also ensures that after - * having done so that this RectBounds instance is normalized. - */ - public void setBoundsAndSort(float minX, float minY, float maxX, - float maxY) { - setBounds(minX, minY, maxX, maxY); - sortMinMax(); - } - - @Override - public void setBoundsAndSort(float minX, float minY, float minZ, float maxX, - float maxY, float maxZ) { - if (minZ != 0 || maxZ != 0) { - throw new UnsupportedOperationException("Unknown BoundsType"); - } - setBounds(minX, minY, maxX, maxY); - sortMinMax(); - } - - @Override - public void setBoundsAndSort(Point2D p1, Point2D p2) { - setBoundsAndSort(p1.x, p1.y, p2.x, p2.y); - } - - public void setMaxX(float maxX) { - this.maxX = maxX; - } - - public void setMaxY(float maxY) { - this.maxY = maxY; - } - - public void setMinX(float minX) { - this.minX = minX; - } - - public void setMinY(float minY) { - this.minY = minY; - } - - @Override - public String toString() { - return "RectBounds { minX:" + minX + ", minY:" + minY + ", maxX:" + maxX - + ", maxY:" + maxY + "} (w:" + (maxX - minX) + ", h:" - + (maxY - minY) + ")"; - } - - @Override - public void translate(float x, float y, float z) { - setMinX(getMinX() + x); - setMinY(getMinY() + y); - setMaxX(getMaxX() + x); - setMaxY(getMaxY() + y); - } - - public void unionWith(float minX, float minY, float maxX, float maxY) { - // Short circuit union if either bounds is empty. - if ((maxX < minX) || (maxY < minY)) { - return; - } - if (this.isEmpty()) { - setBounds(minX, minY, maxX, maxY); - return; - } - - this.minX = Math.min(this.minX, minX); - this.minY = Math.min(this.minY, minY); - this.maxX = Math.max(this.maxX, maxX); - this.maxY = Math.max(this.maxY, maxY); - } - - public void unionWith(RectBounds other) { - // Short circuit union if either bounds is empty. - if (other.isEmpty()) { - return; - } - if (this.isEmpty()) { - setBounds(other); - return; - } - - minX = Math.min(minX, other.getMinX()); - minY = Math.min(minY, other.getMinY()); - maxX = Math.max(maxX, other.getMaxX()); - maxY = Math.max(maxY, other.getMaxY()); - } - - @Override - protected void sortMinMax() { - if (minX > maxX) { - float tmp = maxX; - maxX = minX; - minX = tmp; - } - if (minY > maxY) { - float tmp = maxY; - maxY = minY; - minY = tmp; - } - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Rectangle.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Rectangle.java deleted file mode 100644 index 0185735..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Rectangle.java +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Copyright (c) 1995, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * A Rectangle specifies an area in a coordinate space that is - * enclosed by the Rectangle object's upper-left point - * {@code (x, y)} in the coordinate space, its width, and its height. - *

- * A Rectangle object's width and height - * are public fields. The constructors that create a - * Rectangle, and the methods that can modify one, do not prevent - * setting a negative value for width or height. - *

- * A {@code Rectangle} whose width or height is exactly zero - * has location along those axes with zero dimension, but is otherwise - * considered empty. The {@link #isEmpty} method will return true for such a - * {@code Rectangle}. Methods which test if an empty {@code Rectangle} contains - * or intersects a point or rectangle will always return false if either - * dimension is zero. Methods which combine such a {@code Rectangle} with a - * point or rectangle will include the location of the {@code Rectangle} on that - * axis in the result as if the {@link #add(Point)} method were being called. - * - *

- * A {@code Rectangle} whose width or height is negative - * has neither location nor dimension along those axes with negative dimensions. - * Such a {@code Rectangle} is treated as non-existant along those axes. Such a - * {@code Rectangle} is also empty with respect to containment calculations and - * methods which test if it contains or intersects a point or rectangle will - * always return false. Methods which combine such a {@code Rectangle} with a - * point or rectangle will ignore the {@code Rectangle} entirely in generating - * the result. If two {@code Rectangle} objects are combined and each has a - * negative dimension, the result will have at least one negative dimension. - * - *

- * Methods which affect only the location of a {@code Rectangle} will operate on - * its location regardless of whether or not it has a negative or zero dimension - * along either axis. - *

- * Note that a {@code Rectangle} constructed with the default no-argument - * constructor will have dimensions of {@code 0x0} and therefore be empty. That - * {@code Rectangle} will still have a location of {@code (0, 0)} and will - * contribute that location to the union and add operations. Code attempting to - * accumulate the bounds of a set of points should therefore initially construct - * the {@code Rectangle} with a specifically negative width and height or it - * should use the first point in the set to construct the {@code Rectangle}. For - * example: - * - *

- * Rectangle bounds = new Rectangle(0, 0, -1, -1);
- * for (int i = 0; i < points.length; i++) {
- *     bounds.add(points[i]);
- * }
- * 
- * - * or if we know that the points array contains at least one point: - * - *
- * Rectangle bounds = new Rectangle(points[0]);
- * for (int i = 1; i < points.length; i++) {
- *     bounds.add(points[i]);
- * }
- * 
- *

- * This class uses 32-bit integers to store its location and dimensions. - * Frequently operations may produce a result that exceeds the range of a 32-bit - * integer. The methods will calculate their results in a way that avoids any - * 32-bit overflow for intermediate results and then choose the best - * representation to store the final results back into the 32-bit fields which - * hold the location and dimensions. The location of the result will be stored - * into the {@link #x} and {@link #y} fields by clipping the true result to the - * nearest 32-bit value. The values stored into the {@link #width} and - * {@link #height} dimension fields will be chosen as the 32-bit values that - * encompass the largest part of the true result as possible. Generally this - * means that the dimension will be clipped independently to the range of 32-bit - * integers except that if the location had to be moved to store it into its - * pair of 32-bit fields then the dimensions will be adjusted relative to the - * "best representation" of the location. If the true result had a negative - * dimension and was therefore non-existant along one or both axes, the stored - * dimensions will be negative numbers in those axes. If the true result had a - * location that could be represented within the range of 32-bit integers, but - * zero dimension along one or both axes, then the stored dimensions will be - * zero in those axes. - */ -public class Rectangle { - - /** - * The height of the Rectangle. - */ - public int height; - - /** - * The width of the Rectangle. - */ - public int width; - - /** - * The X coordinate of the upper-left corner of the Rectangle. - */ - public int x; - - /** - * The Y coordinate of the upper-left corner of the Rectangle. - */ - public int y; - - /** - * Constructs a new Rectangle whose upper-left corner is at - * (0, 0) in the coordinate space, and whose width and height are both - * zero. - */ - public Rectangle() { - this(0, 0, 0, 0); - } - - /** - * Constructs a new Rectangle, initialized to match the values - * of the specified Rectangle. - * - * @param r - * the Rectangle from which to copy initial values - * to a newly constructed Rectangle - */ - public Rectangle(BaseBounds b) { - setBounds(b); - } - - /** - * Constructs a new Rectangle whose upper-left corner is at - * (0, 0) in the coordinate space, and whose width and height are - * specified by the arguments of the same name. - * - * @param width - * the width of the Rectangle - * @param height - * the height of the Rectangle - */ - public Rectangle(int width, int height) { - this(0, 0, width, height); - } - - /** - * Constructs a new Rectangle whose upper-left corner is - * specified as {@code (x, y)} and whose width and height are specified by - * the arguments of the same name. - * - * @param x - * the specified X coordinate - * @param y - * the specified Y coordinate - * @param width - * the width of the Rectangle - * @param height - * the height of the Rectangle - */ - public Rectangle(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - /** - * Constructs a new Rectangle, initialized to match the values - * of the specified BaseBounds. Since BaseBounds has float - * values, the Rectangle will be created such that the bounding rectangle of - * the specified BaseBounds would always lie within the bounding box - * specified by this Rectangle. - * - * @param r - * the BaseBounds from which to copy initial values - * to a newly constructed Rectangle - */ - public Rectangle(Rectangle r) { - this(r.x, r.y, r.width, r.height); - } - - /** - * Adds a point, specified by the integer arguments {@code newx, newy} to - * the bounds of this {@code Rectangle}. - *

- * If this {@code Rectangle} has any dimension less than zero, the rules for - * non-existant rectangles apply. In that case, the - * new bounds of this {@code Rectangle} will have a location equal to the - * specified coordinates and width and height equal to zero. - *

- * After adding a point, a call to contains with the added - * point as an argument does not necessarily return true. The - * contains method does not return true for points - * on the right or bottom edges of a Rectangle. Therefore, if - * the added point falls on the right or bottom edge of the enlarged - * Rectangle, contains returns false - * for that point. If the specified point must be contained within the new - * {@code Rectangle}, a 1x1 rectangle should be added instead: - * - *

-     * r.add(newx, newy, 1, 1);
-     * 
- * - * @param newx - * the X coordinate of the new point - * @param newy - * the Y coordinate of the new point - */ - public void add(int newx, int newy) { - if ((width | height) < 0) { - this.x = newx; - this.y = newy; - this.width = this.height = 0; - return; - } - int x1 = this.x; - int y1 = this.y; - long x2 = this.width; - long y2 = this.height; - x2 += x1; - y2 += y1; - if (x1 > newx) { - x1 = newx; - } - if (y1 > newy) { - y1 = newy; - } - if (x2 < newx) { - x2 = newx; - } - if (y2 < newy) { - y2 = newy; - } - x2 -= x1; - y2 -= y1; - if (x2 > Integer.MAX_VALUE) { - x2 = Integer.MAX_VALUE; - } - if (y2 > Integer.MAX_VALUE) { - y2 = Integer.MAX_VALUE; - } - reshape(x1, y1, (int) x2, (int) y2); - } - - /** - * Adds a Rectangle to this Rectangle. The - * resulting Rectangle is the union of the two rectangles. - *

- * If either {@code Rectangle} has any dimension less than 0, the result - * will have the dimensions of the other {@code Rectangle}. If both - * {@code Rectangle}s have at least one dimension less than 0, the result - * will have at least one dimension less than 0. - *

- * If either {@code Rectangle} has one or both dimensions equal to 0, the - * result along those axes with 0 dimensions will be equivalent to the - * results obtained by adding the corresponding origin coordinate to the - * result rectangle along that axis, similar to the operation of the - * {@link #add(Point)} method, but contribute no further dimension beyond - * that. - *

- * If the resulting {@code Rectangle} would have a dimension too large to be - * expressed as an {@code int}, the result will have a dimension of - * {@code Integer.MAX_VALUE} along that dimension. - * - * @param r - * the specified Rectangle - */ - public void add(Rectangle r) { - long tx2 = this.width; - long ty2 = this.height; - if ((tx2 | ty2) < 0) { - reshape(r.x, r.y, r.width, r.height); - } - long rx2 = r.width; - long ry2 = r.height; - if ((rx2 | ry2) < 0) { - return; - } - int tx1 = this.x; - int ty1 = this.y; - tx2 += tx1; - ty2 += ty1; - int rx1 = r.x; - int ry1 = r.y; - rx2 += rx1; - ry2 += ry1; - if (tx1 > rx1) { - tx1 = rx1; - } - if (ty1 > ry1) { - ty1 = ry1; - } - if (tx2 < rx2) { - tx2 = rx2; - } - if (ty2 < ry2) { - ty2 = ry2; - } - tx2 -= tx1; - ty2 -= ty1; - // tx2,ty2 will never underflow since both original - // rectangles were non-empty - // they might overflow, though... - if (tx2 > Integer.MAX_VALUE) { - tx2 = Integer.MAX_VALUE; - } - if (ty2 > Integer.MAX_VALUE) { - ty2 = Integer.MAX_VALUE; - } - reshape(tx1, ty1, (int) tx2, (int) ty2); - } - - /** - * Checks whether or not this Rectangle contains the point at - * the specified location {@code (cx, cy)}. - * - * @param cx - * the specified X coordinate - * @param cy - * the specified Y coordinate - * @return true if the point {@code (cx, cy)} is inside this - * Rectangle; false otherwise. - */ - public boolean contains(int cx, int cy) { - int tw = this.width; - int th = this.height; - if ((tw | th) < 0) { - // At least one of the dimensions is negative... - return false; - } - // Note: if either dimension is zero, tests below must return false... - int tx = this.x; - int ty = this.y; - if (cx < tx || cy < ty) { - return false; - } - tw += tx; - th += ty; - // overflow || intersect - return ((tw < tx || tw > cx) && (th < ty || th > cy)); - } - - /** - * Checks whether this Rectangle entirely contains the - * Rectangle at the specified location {@code (cx, cy)} with - * the specified dimensions {@code (cw, ch)}. - * - * @param cx - * the specified X coordinate - * @param cy - * the specified Y coordinate - * @param cw - * the width of the Rectangle - * @param ch - * the height of the Rectangle - * @return true if the Rectangle specified by - * {@code (cx, cy, cw, ch)} is entirely enclosed inside this - * Rectangle; false otherwise. - */ - public boolean contains(int cx, int cy, int cw, int ch) { - int tw = this.width; - int th = this.height; - if ((tw | th | cw | ch) < 0) { - // At least one of the dimensions is negative... - return false; - } - // Note: if any dimension is zero, tests below must return false... - int tx = this.x; - int ty = this.y; - if (cx < tx || cy < ty) { - return false; - } - tw += tx; - cw += cx; - if (cw <= cx) { - // cx+cw overflowed or cw was zero, return false if... - // either original tw or cw was zero or - // tx+tw did not overflow or - // the overflowed cx+cw is smaller than the overflowed tx+tw - if (tw >= tx || cw > tw) { - return false; - } - } else { - // cx+cw did not overflow and cw was not zero, return false if... - // original tw was zero or - // tx+tw did not overflow and tx+tw is smaller than cx+cw - if (tw >= tx && cw > tw) { - return false; - } - } - th += ty; - ch += cy; - if (ch <= cy) { - if (th >= ty || ch > th) { - return false; - } - } else { - if (th >= ty && ch > th) { - return false; - } - } - return true; - } - - /** - * Checks whether or not this Rectangle entirely contains the - * specified Rectangle. - * - * @param r - * the specified Rectangle - * @return true if the Rectangle is contained - * entirely inside this Rectangle; false - * otherwise - */ - public boolean contains(Rectangle r) { - return contains(r.x, r.y, r.width, r.height); - } - - /** - * Checks whether two rectangles are equal. - *

- * The result is true if and only if the argument is not - * null and is a Rectangle object that has the - * same upper-left corner, width, and height as this Rectangle. - * - * @param obj - * the Object to compare with this - * Rectangle - * @return true if the objects are equal; false - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof Rectangle) { - Rectangle r = (Rectangle) obj; - return ((x == r.x) && (y == r.y) && (width == r.width) - && (height == r.height)); - } - return super.equals(obj); - } - - /** - * Resizes the Rectangle both horizontally and vertically. - *

- * This method modifies the Rectangle so that it is - * h units larger on both the left and right side, and - * v units larger at both the top and bottom. - *

- * The new Rectangle has {@code (x - h, y - v)} as its - * upper-left corner, width of {@code (width + 2h)}, and a height of - * {@code (height + 2v)}. - *

- * If negative values are supplied for h and v, - * the size of the Rectangle decreases accordingly. The - * {@code grow} method will check for integer overflow and underflow, but - * does not check whether the resulting values of {@code width} and - * {@code height} grow from negative to non-negative or shrink from - * non-negative to negative. - * - * @param h - * the horizontal expansion - * @param v - * the vertical expansion - */ - public void grow(int h, int v) { - long x0 = this.x; - long y0 = this.y; - long x1 = this.width; - long y1 = this.height; - x1 += x0; - y1 += y0; - - x0 -= h; - y0 -= v; - x1 += h; - y1 += v; - - if (x1 < x0) { - // Non-existant in X direction - // Final width must remain negative so subtract x0 before - // it is clipped so that we avoid the risk that the clipping - // of x0 will reverse the ordering of x0 and x1. - x1 -= x0; - if (x1 < Integer.MIN_VALUE) { - x1 = Integer.MIN_VALUE; - } - if (x0 < Integer.MIN_VALUE) { - x0 = Integer.MIN_VALUE; - } else if (x0 > Integer.MAX_VALUE) { - x0 = Integer.MAX_VALUE; - } - } else { // (x1 >= x0) - // Clip x0 before we subtract it from x1 in case the clipping - // affects the representable area of the rectangle. - if (x0 < Integer.MIN_VALUE) { - x0 = Integer.MIN_VALUE; - } else if (x0 > Integer.MAX_VALUE) { - x0 = Integer.MAX_VALUE; - } - x1 -= x0; - // The only way x1 can be negative now is if we clipped - // x0 against MIN and x1 is less than MIN - in which case - // we want to leave the width negative since the result - // did not intersect the representable area. - if (x1 < Integer.MIN_VALUE) { - x1 = Integer.MIN_VALUE; - } else if (x1 > Integer.MAX_VALUE) { - x1 = Integer.MAX_VALUE; - } - } - - if (y1 < y0) { - // Non-existant in Y direction - y1 -= y0; - if (y1 < Integer.MIN_VALUE) { - y1 = Integer.MIN_VALUE; - } - if (y0 < Integer.MIN_VALUE) { - y0 = Integer.MIN_VALUE; - } else if (y0 > Integer.MAX_VALUE) { - y0 = Integer.MAX_VALUE; - } - } else { // (y1 >= y0) - if (y0 < Integer.MIN_VALUE) { - y0 = Integer.MIN_VALUE; - } else if (y0 > Integer.MAX_VALUE) { - y0 = Integer.MAX_VALUE; - } - y1 -= y0; - if (y1 < Integer.MIN_VALUE) { - y1 = Integer.MIN_VALUE; - } else if (y1 > Integer.MAX_VALUE) { - y1 = Integer.MAX_VALUE; - } - } - - reshape((int) x0, (int) y0, (int) x1, (int) y1); - } - - @Override - public int hashCode() { - int bits = Float.floatToIntBits(x); - bits += Float.floatToIntBits(y) * 37; - bits += Float.floatToIntBits(width) * 43; - bits += Float.floatToIntBits(height) * 47; - return bits; - } - - public Rectangle intersection(Rectangle r) { - Rectangle ret = new Rectangle(this); - ret.intersectWith(r); - return ret; - } - - public void intersectWith(Rectangle r) { - if (r == null) { - return; - } - int tx1 = this.x; - int ty1 = this.y; - int rx1 = r.x; - int ry1 = r.y; - long tx2 = tx1; - tx2 += this.width; - long ty2 = ty1; - ty2 += this.height; - long rx2 = rx1; - rx2 += r.width; - long ry2 = ry1; - ry2 += r.height; - if (tx1 < rx1) { - tx1 = rx1; - } - if (ty1 < ry1) { - ty1 = ry1; - } - if (tx2 > rx2) { - tx2 = rx2; - } - if (ty2 > ry2) { - ty2 = ry2; - } - tx2 -= tx1; - ty2 -= ty1; - // tx2,ty2 will never overflow (they will never be - // larger than the smallest of the two source w,h) - // they might underflow, though... - if (tx2 < Integer.MIN_VALUE) { - tx2 = Integer.MIN_VALUE; - } - if (ty2 < Integer.MIN_VALUE) { - ty2 = Integer.MIN_VALUE; - } - setBounds(tx1, ty1, (int) tx2, (int) ty2); - } - - /** - * {@inheritDoc} - */ - public boolean isEmpty() { - return (width <= 0) || (height <= 0); - } - - public void setBounds(BaseBounds b) { - x = (int) Math.floor(b.getMinX()); - y = (int) Math.floor(b.getMinY()); - int x2 = (int) Math.ceil(b.getMaxX()); - int y2 = (int) Math.ceil(b.getMaxY()); - width = x2 - x; - height = y2 - y; - } - - /** - * Sets the bounding Rectangle of this Rectangle - * to the specified x, y, width, and - * height. - *

- * This method is included for completeness, to parallel the - * setBounds method of Component. - * - * @param x - * the new X coordinate for the upper-left corner of this - * Rectangle - * @param y - * the new Y coordinate for the upper-left corner of this - * Rectangle - * @param width - * the new width for this Rectangle - * @param height - * the new height for this Rectangle - * @see #getBounds - * @see java.awt.Component#setBounds(int, int, int, int) - */ - public void setBounds(int x, int y, int width, int height) { - reshape(x, y, width, height); - } - - /** - * Sets the bounding Rectangle of this Rectangle - * to match the specified Rectangle. - *

- * This method is included for completeness, to parallel the - * setBounds method of Component. - * - * @param r - * the specified Rectangle - * @see #getBounds - * @see java.awt.Component#setBounds(java.awt.Rectangle) - */ - public void setBounds(Rectangle r) { - setBounds(r.x, r.y, r.width, r.height); - } - - public RectBounds toRectBounds() { - return new RectBounds(x, y, x + width, y + height); - } - - /** - * Returns a String representing this Rectangle - * and its values. - * - * @return a String representing this Rectangle - * object's coordinate and size values. - */ - @Override - public String toString() { - return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width - + ",height=" + height + "]"; - } - - /** - * Translates this Rectangle the indicated distance, to the - * right along the X coordinate axis, and downward along the Y coordinate - * axis. - * - * @param dx - * the distance to move this Rectangle along the X - * axis - * @param dy - * the distance to move this Rectangle along the Y - * axis - * @see java.awt.Rectangle#setLocation(int, int) - * @see java.awt.Rectangle#setLocation(java.awt.Point) - */ - public void translate(int dx, int dy) { - int oldv = this.x; - int newv = oldv + dx; - if (dx < 0) { - // moving leftward - if (newv > oldv) { - // negative overflow - // Only adjust width if it was valid (>= 0). - if (width >= 0) { - // The right edge is now conceptually at - // newv+width, but we may move newv to prevent - // overflow. But we want the right edge to - // remain at its new location in spite of the - // clipping. Think of the following adjustment - // conceptually the same as: - // width += newv; newv = MIN_VALUE; width -= newv; - width += newv - Integer.MIN_VALUE; - // width may go negative if the right edge went past - // MIN_VALUE, but it cannot overflow since it cannot - // have moved more than MIN_VALUE and any non-negative - // number + MIN_VALUE does not overflow. - } - newv = Integer.MIN_VALUE; - } - } else { - // moving rightward (or staying still) - if (newv < oldv) { - // positive overflow - if (width >= 0) { - // Conceptually the same as: - // width += newv; newv = MAX_VALUE; width -= newv; - width += newv - Integer.MAX_VALUE; - // With large widths and large displacements - // we may overflow so we need to check it. - if (width < 0) { - width = Integer.MAX_VALUE; - } - } - newv = Integer.MAX_VALUE; - } - } - this.x = newv; - - oldv = this.y; - newv = oldv + dy; - if (dy < 0) { - // moving upward - if (newv > oldv) { - // negative overflow - if (height >= 0) { - height += newv - Integer.MIN_VALUE; - // See above comment about no overflow in this case - } - newv = Integer.MIN_VALUE; - } - } else { - // moving downward (or staying still) - if (newv < oldv) { - // positive overflow - if (height >= 0) { - height += newv - Integer.MAX_VALUE; - if (height < 0) { - height = Integer.MAX_VALUE; - } - } - newv = Integer.MAX_VALUE; - } - } - this.y = newv; - } - - private void reshape(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec2f.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec2f.java deleted file mode 100644 index ff2b753..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec2f.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * A 2-dimensional, single-precision, floating-point vector. - */ -public class Vec2f { - /** - * Returns the distance between two points. - * - * @param x1 - * the X coordinate of the first specified point - * @param y1 - * the Y coordinate of the first specified point - * @param x2 - * the X coordinate of the second specified point - * @param y2 - * the Y coordinate of the second specified point - * @return the distance between the two sets of specified coordinates. - */ - public static float distance(float x1, float y1, float x2, float y2) { - x1 -= x2; - y1 -= y2; - return (float) Math.sqrt(x1 * x1 + y1 * y1); - } - - /** - * Returns the square of the distance between two points. - * - * @param x1 - * the X coordinate of the first specified point - * @param y1 - * the Y coordinate of the first specified point - * @param x2 - * the X coordinate of the second specified point - * @param y2 - * the Y coordinate of the second specified point - * @return the square of the distance between the two sets of specified - * coordinates. - */ - public static float distanceSq(float x1, float y1, float x2, float y2) { - x1 -= x2; - y1 -= y2; - return (x1 * x1 + y1 * y1); - } - - /** - * The x coordinate. - */ - public float x; - - /** - * The y coordinate. - */ - public float y; - - public Vec2f() { - } - - public Vec2f(float x, float y) { - this.x = x; - this.y = y; - } - - public Vec2f(Vec2f v) { - this.x = v.x; - this.y = v.y; - } - - /** - * Returns the distance from this Vec2f to a specified point. - * - * @param vx - * the X coordinate of the specified point to be measured against - * this Vec2f - * @param vy - * the Y coordinate of the specified point to be measured against - * this Vec2f - * @return the distance between this Vec2f and a specified - * point. - */ - public float distance(float vx, float vy) { - vx -= x; - vy -= y; - return (float) Math.sqrt(vx * vx + vy * vy); - } - - /** - * Returns the distance from this Vec2f to a specified - * Vec2f. - * - * @param v - * the specified point to be measured against this - * Vec2f - * @return the distance between this Vec2f and the specified - * Vec2f. - */ - public float distance(Vec2f v) { - float vx = v.x - this.x; - float vy = v.y - this.y; - return (float) Math.sqrt(vx * vx + vy * vy); - } - - /** - * Returns the square of the distance from this Vec2f to a - * specified point. - * - * @param vx - * the X coordinate of the specified point to be measured against - * this Vec2f - * @param vy - * the Y coordinate of the specified point to be measured against - * this Vec2f - * @return the square of the distance between this Vec2f and - * the specified point. - */ - public float distanceSq(float vx, float vy) { - vx -= x; - vy -= y; - return (vx * vx + vy * vy); - } - - /** - * Returns the square of the distance from this Vec2f to a - * specified Vec2f. - * - * @param v - * the specified point to be measured against this - * Vec2f - * @return the square of the distance between this Vec2f to a - * specified Vec2f. - */ - public float distanceSq(Vec2f v) { - float vx = v.x - this.x; - float vy = v.y - this.y; - return (vx * vx + vy * vy); - } - - /** - * Determines whether or not two 2D points or vectors are equal. Two - * instances of Vec2f are equal if the values of their - * x and y member fields, representing their - * position in the coordinate space, are the same. - * - * @param obj - * an object to be compared with this Vec2f - * @return true if the object to be compared is an instance of - * Vec2f and has the same values; false - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Vec2f) { - Vec2f v = (Vec2f) obj; - return (x == v.x) && (y == v.y); - } - return false; - } - - /** - * Returns the hashcode for this Vec2f. - * - * @return a hash code for this Vec2f. - */ - @Override - public int hashCode() { - int bits = 7; - bits = 31 * bits + Float.floatToIntBits(x); - bits = 31 * bits + Float.floatToIntBits(y); - return bits; - } - - /** - * Sets the location of this Vec2f to the specified - * float coordinates. - * - * @param x - * the new X coordinate of this {@code Vec2f} - * @param y - * the new Y coordinate of this {@code Vec2f} - */ - public void set(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Sets the location of this Vec2f to the same coordinates as - * the specified Vec2f object. - * - * @param v - * the specified Vec2f to which to set this - * Vec2f - */ - public void set(Vec2f v) { - this.x = v.x; - this.y = v.y; - } - - /** - * Returns a String that represents the value of this - * Vec2f. - * - * @return a string representation of this Vec2f. - */ - @Override - public String toString() { - return "Vec2f[" + x + ", " + y + "]"; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3d.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3d.java deleted file mode 100644 index 881bfa7..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3d.java +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * A 3-dimensional, double-precision, floating-point vector. - */ -public class Vec3d { - /** - * The x coordinate. - */ - public double x; - - /** - * The y coordinate. - */ - public double y; - - /** - * The z coordinate. - */ - public double z; - - public Vec3d() { - } - - public Vec3d(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Vec3d(Vec3d v) { - set(v); - } - - public Vec3d(Vec3f v) { - set(v); - } - - /** - * Sets the value of this vector to the sum of itself and vector t1 (this = - * this + t1) . - * - * @param t1 - * the other vector - */ - public void add(Vec3d t1) { - this.x += t1.x; - this.y += t1.y; - this.z += t1.z; - } - - /** - * Sets the value of this vector to the sum of vectors t1 and t2 (this = t1 - * + t2). - * - * @param t1 - * the first vector - * @param t2 - * the second vector - */ - public void add(Vec3d t1, Vec3d t2) { - this.x = t1.x + t2.x; - this.y = t1.y + t2.y; - this.z = t1.z + t2.z; - } - - /** - * Sets this vector to be the vector cross product of vectors v1 and v2. - * - * @param v1 - * the first vector - * @param v2 - * the second vector - */ - public void cross(Vec3d v1, Vec3d v2) { - double tmpX; - double tmpY; - - tmpX = v1.y * v2.z - v1.z * v2.y; - tmpY = v2.x * v1.z - v2.z * v1.x; - this.z = v1.x * v2.y - v1.y * v2.x; - this.x = tmpX; - this.y = tmpY; - } - - /** - * Computes the dot product of this vector and vector v1. - * - * @param v1 - * the other vector - * @return the dot product of this vector and v1 - */ - public double dot(Vec3d v1) { - return this.x * v1.x + this.y * v1.y + this.z * v1.z; - } - - /** - * Determines whether or not two 3D points or vectors are equal. Two - * instances of Vec3d are equal if the values of their - * x, y and z member fields, - * representing their position in the coordinate space, are the same. - * - * @param obj - * an object to be compared with this Vec3d - * @return true if the object to be compared is an instance of - * Vec3d and has the same values; false - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Vec3d) { - Vec3d v = (Vec3d) obj; - return (x == v.x) && (y == v.y) && (z == v.z); - } - return false; - } - - /** - * Returns the hashcode for this Vec3f. - * - * @return a hash code for this Vec3f. - */ - @Override - public int hashCode() { - long bits = 7L; - bits = 31L * bits + Double.doubleToLongBits(x); - bits = 31L * bits + Double.doubleToLongBits(y); - bits = 31L * bits + Double.doubleToLongBits(z); - return (int) (bits ^ (bits >> 32)); - } - - /** - * Returns the length of this vector. - * - * @return the length of this vector - */ - public double length() { - return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); - } - - /** - * Multiplies this vector by the specified scalar value. - * - * @param scale - * the scalar value - */ - public void mul(double scale) { - x *= scale; - y *= scale; - z *= scale; - } - - /** - * Normalize this vector. - */ - public void normalize() { - double norm = 1.0 / length(); - this.x = this.x * norm; - this.y = this.y * norm; - this.z = this.z * norm; - } - - public void set(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public void set(Vec3d v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - - public void set(Vec3f v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - - /** - * Sets the value of this vector to the difference of itself and vector t1 - * (this = this - t1) . - * - * @param t1 - * the other vector - */ - public void sub(Vec3d t1) { - this.x -= t1.x; - this.y -= t1.y; - this.z -= t1.z; - } - - /** - * Sets the value of this vector to the difference of vectors t1 and t2 - * (this = t1 - t2). - * - * @param t1 - * the first vector - * @param t2 - * the second vector - */ - public void sub(Vec3d t1, Vec3d t2) { - this.x = t1.x - t2.x; - this.y = t1.y - t2.y; - this.z = t1.z - t2.z; - } - - /** - * Sets the value of this vector to the difference of vectors t1 and t2 - * (this = t1 - t2). - * - * @param t1 - * the first vector - * @param t2 - * the second vector - */ - public void sub(Vec3f t1, Vec3f t2) { - this.x = t1.x - t2.x; - this.y = t1.y - t2.y; - this.z = t1.z - t2.z; - } - - /** - * Returns a String that represents the value of this - * Vec3f. - * - * @return a string representation of this Vec3f. - */ - @Override - public String toString() { - return "Vec3d[" + x + ", " + y + ", " + z + "]"; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3f.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3f.java deleted file mode 100644 index d0d4723..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/Vec3f.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom; - -/** - * A 3-dimensional, single-precision, floating-point vector. - */ -public class Vec3f { - /** - * The x coordinate. - */ - public float x; - - /** - * The y coordinate. - */ - public float y; - - /** - * The z coordinate. - */ - public float z; - - public Vec3f() { - } - - public Vec3f(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Vec3f(Vec3f v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - - /** - * Sets the value of this vector to the sum of itself and vector t1 (this = - * this + t1) . - * - * @param t1 - * the other vector - */ - public void add(Vec3f t1) { - this.x += t1.x; - this.y += t1.y; - this.z += t1.z; - } - - /** - * Sets the value of this vector to the sum of vectors t1 and t2 (this = t1 - * + t2). - * - * @param t1 - * the first vector - * @param t2 - * the second vector - */ - public void add(Vec3f t1, Vec3f t2) { - this.x = t1.x + t2.x; - this.y = t1.y + t2.y; - this.z = t1.z + t2.z; - } - - /** - * Sets this vector to be the vector cross product of vectors v1 and v2. - * - * @param v1 - * the first vector - * @param v2 - * the second vector - */ - public void cross(Vec3f v1, Vec3f v2) { - float tmpX; - float tmpY; - - tmpX = v1.y * v2.z - v1.z * v2.y; - tmpY = v2.x * v1.z - v2.z * v1.x; - this.z = v1.x * v2.y - v1.y * v2.x; - this.x = tmpX; - this.y = tmpY; - } - - /** - * Computes the dot product of this vector and vector v1. - * - * @param v1 - * the other vector - * @return the dot product of this vector and v1 - */ - public float dot(Vec3f v1) { - return this.x * v1.x + this.y * v1.y + this.z * v1.z; - } - - /** - * Determines whether or not two 3D points or vectors are equal. Two - * instances of Vec3f are equal if the values of their - * x, y and z member fields, - * representing their position in the coordinate space, are the same. - * - * @param obj - * an object to be compared with this Vec3f - * @return true if the object to be compared is an instance of - * Vec3f and has the same values; false - * otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Vec3f) { - Vec3f v = (Vec3f) obj; - return (x == v.x) && (y == v.y) && (z == v.z); - } - return false; - } - - /** - * Returns the hashcode for this Vec3f. - * - * @return a hash code for this Vec3f. - */ - @Override - public int hashCode() { - int bits = 7; - bits = 31 * bits + Float.floatToIntBits(x); - bits = 31 * bits + Float.floatToIntBits(y); - bits = 31 * bits + Float.floatToIntBits(z); - return bits; - } - - /** - * Returns the length of this vector. - * - * @return the length of this vector - */ - public float length() { - return (float) Math.sqrt(this.x * this.x + this.y * this.y - + this.z * this.z); - } - - public final void mul(float s) { - this.x *= s; - this.y *= s; - this.z *= s; - } - - /** - * Normalize this vector. - */ - public void normalize() { - float norm = 1.0f / length(); - this.x = this.x * norm; - this.y = this.y * norm; - this.z = this.z * norm; - } - - public void set(float x, float y, float z) { - this.x = x; - this.y = y; - this.z = z; - } - - public void set(Vec3f v) { - this.x = v.x; - this.y = v.y; - this.z = v.z; - } - - /** - * Sets the value of this vector to the difference of itself and vector t1 - * (this = this - t1) . - * - * @param t1 - * the other vector - */ - public void sub(Vec3f t1) { - this.x -= t1.x; - this.y -= t1.y; - this.z -= t1.z; - } - - /** - * Sets the value of this vector to the difference of vectors t1 and t2 - * (this = t1 - t2). - * - * @param t1 - * the first vector - * @param t2 - * the second vector - */ - public void sub(Vec3f t1, Vec3f t2) { - this.x = t1.x - t2.x; - this.y = t1.y - t2.y; - this.z = t1.z - t2.z; - } - - /** - * Returns a String that represents the value of this - * Vec3f. - * - * @return a string representation of this Vec3f. - */ - @Override - public String toString() { - return "Vec3f[" + x + ", " + y + ", " + z + "]"; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine2D.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine2D.java deleted file mode 100644 index 21f086d..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine2D.java +++ /dev/null @@ -1,1532 +0,0 @@ -/* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.Point2D; - -/** - * The Affine2D class represents a 2D affine transform that - * performs a linear mapping from 2D coordinates to other 2D coordinates that - * preserves the "straightness" and "parallelness" of lines. Affine - * transformations can be constructed using sequences of translations, scales, - * flips, rotations, and shears. - *

- * Such a coordinate transformation can be represented by a 3 row by 3 column - * matrix with an implied last row of [ 0 0 1 ]. This matrix transforms source - * coordinates {@code (x, y)} into destination coordinates {@code (x', y')} by - * considering them to be a column vector and multiplying the coordinate vector - * by the matrix according to the following process: - * - *

- *  [ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
- *  [ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ]
- *  [ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ]
- * 
- *

- * - *

Handling 90-Degree Rotations

- *

- * In some variations of the rotate methods in the - * Affine2D class, a double-precision argument specifies the angle - * of rotation in radians. These methods have special handling for rotations of - * approximately 90 degrees (including multiples such as 180, 270, and 360 - * degrees), so that the common case of quadrant rotation is handled more - * efficiently. This special handling can cause angles very close to multiples - * of 90 degrees to be treated as if they were exact multiples of 90 degrees. - * For small multiples of 90 degrees the range of angles treated as a quadrant - * rotation is approximately 0.00000121 degrees wide. This section explains why - * such special care is needed and how it is implemented. - *

- * Since 90 degrees is represented as PI/2 in radians, and since PI - * is a transcendental (and therefore irrational) number, it is not possible to - * exactly represent a multiple of 90 degrees as an exact double precision value - * measured in radians. As a result it is theoretically impossible to describe - * quadrant rotations (90, 180, 270 or 360 degrees) using these values. Double - * precision floating point values can get very close to non-zero multiples of - * PI/2 but never close enough for the sine or cosine to be exactly - * 0.0, 1.0 or -1.0. The implementations of Math.sin() and - * Math.cos() correspondingly never return 0.0 for any case other - * than Math.sin(0.0). These same implementations do, however, - * return exactly 1.0 and -1.0 for some range of numbers around each multiple of - * 90 degrees since the correct answer is so close to 1.0 or -1.0 that the - * double precision significand cannot represent the difference as accurately as - * it can for numbers that are near 0.0. - *

- * The net result of these issues is that if the Math.sin() and - * Math.cos() methods are used to directly generate the values for - * the matrix modifications during these radian-based rotation operations then - * the resulting transform is never strictly classifiable as a quadrant rotation - * even for a simple case like rotate(Math.PI/2.0), due to minor - * variations in the matrix caused by the non-0.0 values obtained for the sine - * and cosine. If these transforms are not classified as quadrant rotations then - * subsequent code which attempts to optimize further operations based upon the - * type of the transform will be relegated to its most general implementation. - *

- * Because quadrant rotations are fairly common, this class should handle these - * cases reasonably quickly, both in applying the rotations to the transform and - * in applying the resulting transform to the coordinates. To facilitate this - * optimal handling, the methods which take an angle of rotation measured in - * radians attempt to detect angles that are intended to be quadrant rotations - * and treat them as such. These methods therefore treat an angle theta - * as a quadrant rotation if either Math.sin(theta) or - * Math.cos(theta) returns exactly 1.0 or -1.0. As a rule - * of thumb, this property holds true for a range of approximately 0.0000000211 - * radians (or 0.00000121 degrees) around small multiples of - * Math.PI/2.0. - * - * @version 1.83, 05/05/07 - */ -public class Affine2D extends AffineBase { - private static final long BASE_HASH; - - static { - long bits = 0; - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzz()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzy()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzx()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMyz()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMxz()); - BASE_HASH = bits; - } - - // Round values to sane precision for printing - // Note that Math.sin(Math.PI) has an error of about 10^-16 - private static double _matround(double matval) { - return Math.rint(matval * 1E15) / 1E15; - } - - /** - * Constructs a new Affine2D representing the Identity - * transformation. - */ - public Affine2D() { - mxx = myy = 1.0; - // m01 = m10 = m02 = m12 = 0.0; /* Not needed. */ - // state = APPLY_IDENTITY; /* Not needed. */ - // type = TYPE_IDENTITY; /* Not needed. */ - } - - /** - * Constructs a new Affine2D that uses the same transform as - * the specified BaseTransform object. - * - * @param Tx - * the BaseTransform object to copy - */ - public Affine2D(BaseTransform Tx) { - setTransform(Tx); - } - - /** - * Constructs a new Affine2D from 6 double precision values - * representing the 6 specifiable entries of the 3x3 transformation matrix. - * - * @param mxx - * the X coordinate scaling element of the 3x3 matrix - * @param myx - * the Y coordinate shearing element of the 3x3 matrix - * @param mxy - * the X coordinate shearing element of the 3x3 matrix - * @param myy - * the Y coordinate scaling element of the 3x3 matrix - * @param mxt - * the X coordinate translation element of the 3x3 matrix - * @param myt - * the Y coordinate translation element of the 3x3 matrix - */ - public Affine2D(double mxx, double myx, double mxy, double myy, double mxt, - double myt) { - this.mxx = mxx; - this.myx = myx; - this.mxy = mxy; - this.myy = myy; - this.mxt = mxt; - this.myt = myt; - updateState2D(); - } - - /** - * Constructs a new Affine2D from 6 floating point values - * representing the 6 specifiable entries of the 3x3 transformation matrix. - * - * @param mxx - * the X coordinate scaling element of the 3x3 matrix - * @param myx - * the Y coordinate shearing element of the 3x3 matrix - * @param mxy - * the X coordinate shearing element of the 3x3 matrix - * @param myy - * the Y coordinate scaling element of the 3x3 matrix - * @param mxt - * the X coordinate translation element of the 3x3 matrix - * @param myt - * the Y coordinate translation element of the 3x3 matrix - */ - public Affine2D(float mxx, float myx, float mxy, float myy, float mxt, - float myt) { - this.mxx = mxx; - this.myx = myx; - this.mxy = mxy; - this.myy = myy; - this.mxt = mxt; - this.myt = myt; - updateState2D(); - } - - private Affine2D(double mxx, double myx, double mxy, double myy, double mxt, - double myt, int state) { - this.mxx = mxx; - this.myx = myx; - this.mxy = mxy; - this.myy = myy; - this.mxt = mxt; - this.myt = myt; - this.state = state; - this.type = TYPE_UNKNOWN; - } - - @Override - public BaseTransform copy() { - return new Affine2D(this); - } - - /** - * Returns an Affine2D object representing the inverse - * transformation. The inverse transform Tx' of this transform Tx maps - * coordinates transformed by Tx back to their original coordinates. In - * other words, Tx'(Tx(p)) = p = Tx(Tx'(p)). - *

- * If this transform maps all coordinates onto a point or a line then it - * will not have an inverse, since coordinates that do not lie on the - * destination point or line will not have an inverse mapping. The - * getDeterminant method can be used to determine if this - * transform has no inverse, in which case an exception will be thrown if - * the createInverse method is called. - * - * @return a new Affine2D object representing the inverse - * transformation. - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - * @see #getDeterminant - */ - @Override - public Affine2D createInverse() throws NoninvertibleTransformException { - double det; - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - return new Affine2D(myy / det, -myx / det, -mxy / det, - mxx / det, (mxy * myt - myy * mxt) / det, - (myx * mxt - mxx * myt) / det, - (APPLY_SHEAR | APPLY_SCALE - | APPLY_TRANSLATE)); - case (APPLY_SHEAR | APPLY_SCALE): - det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - return new Affine2D(myy / det, -myx / det, -mxy / det, - mxx / det, 0.0, 0.0, - (APPLY_SHEAR | APPLY_SCALE)); - case (APPLY_SHEAR | APPLY_TRANSLATE): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - return new Affine2D(0.0, 1.0 / mxy, 1.0 / myx, 0.0, -myt / myx, - -mxt / mxy, - (APPLY_SHEAR | APPLY_TRANSLATE)); - case (APPLY_SHEAR): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - return new Affine2D(0.0, 1.0 / mxy, 1.0 / myx, 0.0, 0.0, 0.0, - (APPLY_SHEAR)); - case (APPLY_SCALE | APPLY_TRANSLATE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - return new Affine2D(1.0 / mxx, 0.0, 0.0, 1.0 / myy, -mxt / mxx, - -myt / myy, - (APPLY_SCALE | APPLY_TRANSLATE)); - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - return new Affine2D(1.0 / mxx, 0.0, 0.0, 1.0 / myy, 0.0, 0.0, - (APPLY_SCALE)); - case (APPLY_TRANSLATE): - return new Affine2D(1.0, 0.0, 0.0, 1.0, -mxt, -myt, - (APPLY_TRANSLATE)); - case (APPLY_IDENTITY): - return new Affine2D(); - } - - /* NOTREACHED */ - } - - /** - * Transforms the relative distance vector specified by ptSrc - * and stores the result in ptDst. A relative distance vector - * is transformed without applying the translation components of the affine - * transformation matrix using the following equations: - * - *

-     *  [  x' ]   [  m00  m01 (m02) ] [  x  ]   [ m00x + m01y ]
-     *  [  y' ] = [  m10  m11 (m12) ] [  y  ] = [ m10x + m11y ]
-     *  [ (1) ]   [  (0)  (0) ( 1 ) ] [ (1) ]   [     (1)     ]
-     * 
- * - * If ptDst is null, a new Point2D - * object is allocated and then the result of the transform is stored in - * this object. In either case, ptDst, which contains the - * transformed point, is returned for convenience. If ptSrc and - * ptDst are the same object, the input point is correctly - * overwritten with the transformed point. - * - * @param ptSrc - * the distance vector to be delta transformed - * @param ptDst - * the resulting transformed distance vector - * @return ptDst, which contains the result of the - * transformation. - */ - public Point2D deltaTransform(Point2D ptSrc, Point2D ptDst) { - if (ptDst == null) { - ptDst = new Point2D(); - } - // Copy source coords into local variables in case src == dst - double x = ptSrc.x; - double y = ptSrc.y; - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - ptDst.setLocation((float) (x * mxx + y * mxy), - (float) (x * myx + y * myy)); - return ptDst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - ptDst.setLocation((float) (y * mxy), (float) (x * myx)); - return ptDst; - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - ptDst.setLocation((float) (x * mxx), (float) (y * myy)); - return ptDst; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - ptDst.setLocation((float) x, (float) y); - return ptDst; - } - - /* NOTREACHED */ - } - - @Override - public BaseTransform deriveWithConcatenation(BaseTransform tx) { - if (tx.is2D()) { - concatenate(tx); - return this; - } - Affine3D t3d = new Affine3D(this); - t3d.concatenate(tx); - return t3d; - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double myx, - double mxy, double myy, - double mxt, double myt) { - // TODO: Simplify this (RT-26801) - BaseTransform tmpTx = getInstance(mxx, myx, mxy, myy, mxt, myt); - concatenate(tmpTx); - return this; - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double mxy, - double mxz, double mxt, - double myx, double myy, - double myz, double myt, - double mzx, double mzy, - double mzz, double mzt) { - if (mxz == 0.0 && myz == 0.0 && mzx == 0.0 && mzy == 0.0 && mzz == 1.0 - && mzt == 0.0) { - concatenate(mxx, mxy, mxt, myx, myy, myt); - return this; - } - - Affine3D t3d = new Affine3D(this); - t3d.concatenate(mxx, mxy, mxz, mxt, myx, myy, myz, myt, mzx, mzy, mzz, - mzt); - return t3d; - } - - @Override - public BaseTransform deriveWithNewTransform(BaseTransform tx) { - if (tx.is2D()) { - setTransform(tx); - return this; - } - return getInstance(tx); - } - - @Override - public BaseTransform deriveWithPreConcatenation(BaseTransform tx) { - if (tx.is2D()) { - preConcatenate(tx); - return this; - } - Affine3D t3d = new Affine3D(this); - t3d.preConcatenate(tx); - return t3d; - } - - @Override - public BaseTransform deriveWithPreTranslation(double mxt, double myt) { - this.mxt += mxt; - this.myt += myt; - if (this.mxt != 0.0 || this.myt != 0.0) { - state |= APPLY_TRANSLATE; - // if (type != TYPE_UNKNOWN) { - type |= TYPE_TRANSLATION; - // } - } else { - state &= ~APPLY_TRANSLATE; - if (type != TYPE_UNKNOWN) { - type &= ~TYPE_TRANSLATION; - } - } - return this; - } - - @Override - public BaseTransform deriveWithRotation(double theta, double axisX, - double axisY, double axisZ) { - if (theta == 0.0) { - return this; - } - if (almostZero(axisX) && almostZero(axisY)) { - if (axisZ > 0) { - rotate(theta); - } else if (axisZ < 0) { - rotate(-theta); - } // else rotating about zero vector - NOP - return this; - } - Affine3D a = new Affine3D(this); - a.rotate(theta, axisX, axisY, axisZ); - return a; - } - - @Override - public BaseTransform deriveWithScale(double mxx, double myy, double mzz) { - if (mzz == 1.0) { - scale(mxx, myy); - return this; - } - Affine3D a = new Affine3D(this); - a.scale(mxx, myy, mzz); - return a; - - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt) { - translate(mxt, myt); - return this; - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt, - double mzt) { - if (mzt == 0.0) { - translate(mxt, myt); - return this; - } - Affine3D a = new Affine3D(this); - a.translate(mxt, myt, mzt); - return a; - } - - /** - * Returns true if this Affine2D represents the - * same coordinate transform as the specified argument. - * - * @param obj - * the Object to test for equality with this - * Affine2D - * @return true if obj equals this - * Affine2D object; false otherwise. - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof BaseTransform) { - BaseTransform a = (BaseTransform) obj; - return (a.getType() <= TYPE_AFFINE2D_MASK && a.getMxx() == this.mxx - && a.getMxy() == this.mxy && a.getMxt() == this.mxt - && a.getMyx() == this.myx && a.getMyy() == this.myy - && a.getMyt() == this.myt); - } - return false; - } - - @Override - public Degree getDegree() { - return Degree.AFFINE_2D; - } - - /** - * Returns the hashcode for this transform. The base algorithm for computing - * the hashcode is defined by the implementation in the - * {@code BaseTransform} class. This implementation is just a faster way of - * computing the same value knowing which elements of the transform matrix - * are populated. - * - * @return a hash code for this transform. - */ - @Override - public int hashCode() { - if (isIdentity()) { - return 0; - } - long bits = BASE_HASH; - bits = bits * 31 + Double.doubleToLongBits(getMyy()); - bits = bits * 31 + Double.doubleToLongBits(getMyx()); - bits = bits * 31 + Double.doubleToLongBits(getMxy()); - bits = bits * 31 + Double.doubleToLongBits(getMxx()); - bits = bits * 31 + Double.doubleToLongBits(0.0); // mzt - bits = bits * 31 + Double.doubleToLongBits(getMyt()); - bits = bits * 31 + Double.doubleToLongBits(getMxt()); - return (((int) bits) ^ ((int) (bits >> 32))); - } - - @Override - public boolean is2D() { - return true; - } - - /** - * Concatenates a BaseTransform Tx to this - * Affine2D Cx in a less commonly used way such that - * Tx modifies the coordinate transformation relative to the - * absolute pixel space rather than relative to the existing user space. Cx - * is updated to perform the combined transformation. Transforming a point p - * by the updated transform Cx' is equivalent to first transforming p by the - * original transform Cx and then transforming the result by Tx - * like this: Cx'(p) = Tx(Cx(p)) In matrix notation, if this transform Cx is - * represented by the matrix [this] and Tx is represented by - * the matrix [Tx] then this method does the following: - * - *
-     *      [this] = [Tx] x [this]
-     * 
- * - * @param Tx - * the BaseTransform object to be concatenated with - * this Affine2D object. - * @see #concatenate - */ - public void preConcatenate(BaseTransform Tx) { - switch (Tx.getDegree()) { - case IDENTITY: - return; - case TRANSLATE_2D: - translate(Tx.getMxt(), Tx.getMyt()); - return; - case AFFINE_2D: - break; - default: - degreeError(Degree.AFFINE_2D); - } - double M0, M1; - double Txx, Txy, Tyx, Tyy; - double Txt, Tyt; - int mystate = state; - Affine2D at = (Affine2D) Tx; - int txstate = at.state; - switch ((txstate << HI_SHIFT) | mystate) { - case (HI_IDENTITY | APPLY_IDENTITY): - case (HI_IDENTITY | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SCALE): - case (HI_IDENTITY | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SHEAR): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - // Tx is IDENTITY... - return; - - case (HI_TRANSLATE | APPLY_IDENTITY): - case (HI_TRANSLATE | APPLY_SCALE): - case (HI_TRANSLATE | APPLY_SHEAR): - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE): - // Tx is TRANSLATE, this has no TRANSLATE - mxt = at.mxt; - myt = at.myt; - state = mystate | APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - return; - - case (HI_TRANSLATE | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - // Tx is TRANSLATE, this has one too - mxt = mxt + at.mxt; - myt = myt + at.myt; - return; - - case (HI_SCALE | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_IDENTITY): - // Only these two existing states need a new state - state = mystate | APPLY_SCALE; - /* NOBREAK */ - case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE): - case (HI_SCALE | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SHEAR): - case (HI_SCALE | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SCALE): - // Tx is SCALE, this is anything - Txx = at.mxx; - Tyy = at.myy; - if ((mystate & APPLY_SHEAR) != 0) { - mxy = mxy * Txx; - myx = myx * Tyy; - if ((mystate & APPLY_SCALE) != 0) { - mxx = mxx * Txx; - myy = myy * Tyy; - } - } else { - mxx = mxx * Txx; - myy = myy * Tyy; - } - if ((mystate & APPLY_TRANSLATE) != 0) { - mxt = mxt * Txx; - myt = myt * Tyy; - } - type = TYPE_UNKNOWN; - return; - case (HI_SHEAR | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SHEAR): - mystate = mystate | APPLY_SCALE; - /* NOBREAK */ - case (HI_SHEAR | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_IDENTITY): - case (HI_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SCALE): - state = mystate ^ APPLY_SHEAR; - /* NOBREAK */ - case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE): - // Tx is SHEAR, this is anything - Txy = at.mxy; - Tyx = at.myx; - - M0 = mxx; - mxx = myx * Txy; - myx = M0 * Tyx; - - M0 = mxy; - mxy = myy * Txy; - myy = M0 * Tyx; - - M0 = mxt; - mxt = myt * Txy; - myt = M0 * Tyx; - type = TYPE_UNKNOWN; - return; - } - // If Tx has more than one attribute, it is not worth optimizing - // all of those cases... - Txx = at.mxx; - Txy = at.mxy; - Txt = at.mxt; - Tyx = at.myx; - Tyy = at.myy; - Tyt = at.myt; - switch (mystate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - M0 = mxt; - M1 = myt; - Txt += M0 * Txx + M1 * Txy; - Tyt += M0 * Tyx + M1 * Tyy; - - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - mxt = Txt; - myt = Tyt; - - M0 = mxx; - M1 = myx; - mxx = M0 * Txx + M1 * Txy; - myx = M0 * Tyx + M1 * Tyy; - - M0 = mxy; - M1 = myy; - mxy = M0 * Txx + M1 * Txy; - myy = M0 * Tyx + M1 * Tyy; - break; - - case (APPLY_SHEAR | APPLY_TRANSLATE): - M0 = mxt; - M1 = myt; - Txt += M0 * Txx + M1 * Txy; - Tyt += M0 * Tyx + M1 * Tyy; - - /* NOBREAK */ - case (APPLY_SHEAR): - mxt = Txt; - myt = Tyt; - - M0 = myx; - mxx = M0 * Txy; - myx = M0 * Tyy; - - M0 = mxy; - mxy = M0 * Txx; - myy = M0 * Tyx; - break; - - case (APPLY_SCALE | APPLY_TRANSLATE): - M0 = mxt; - M1 = myt; - Txt += M0 * Txx + M1 * Txy; - Tyt += M0 * Tyx + M1 * Tyy; - - /* NOBREAK */ - case (APPLY_SCALE): - mxt = Txt; - myt = Tyt; - - M0 = mxx; - mxx = M0 * Txx; - myx = M0 * Tyx; - - M0 = myy; - mxy = M0 * Txy; - myy = M0 * Tyy; - break; - - case (APPLY_TRANSLATE): - M0 = mxt; - M1 = myt; - Txt += M0 * Txx + M1 * Txy; - Tyt += M0 * Tyx + M1 * Tyy; - - /* NOBREAK */ - case (APPLY_IDENTITY): - mxt = Txt; - myt = Tyt; - - mxx = Txx; - myx = Tyx; - - mxy = Txy; - myy = Tyy; - - state = mystate | txstate; - type = TYPE_UNKNOWN; - return; - } - updateState2D(); - } - - /** - * Concatenates this transform with a transform that rotates coordinates by - * the specified number of quadrants. This is equivalent to calling: - * - *
-     * rotate(numquadrants * Math.PI / 2.0);
-     * 
- * - * Rotating by a positive number of quadrants rotates points on the positive - * X axis toward the positive Y axis. - * - * @param numquadrants - * the number of 90 degree arcs to rotate by - */ - public void quadrantRotate(int numquadrants) { - switch (numquadrants & 3) { - case 0: - break; - case 1: - rotate90(); - break; - case 2: - rotate180(); - break; - case 3: - rotate270(); - break; - } - } - - /** - * Concatenates this transform with a transform that rotates coordinates by - * the specified number of quadrants around the specified anchor point. This - * method is equivalent to calling: - * - *
-     * rotate(numquadrants * Math.PI / 2.0, anchorx, anchory);
-     * 
- * - * Rotating by a positive number of quadrants rotates points on the positive - * X axis toward the positive Y axis. - * - * @param numquadrants - * the number of 90 degree arcs to rotate by - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void quadrantRotate(int numquadrants, double anchorx, - double anchory) { - switch (numquadrants & 3) { - case 0: - return; - case 1: - mxt += anchorx * (mxx - mxy) + anchory * (mxy + mxx); - myt += anchorx * (myx - myy) + anchory * (myy + myx); - rotate90(); - break; - case 2: - mxt += anchorx * (mxx + mxx) + anchory * (mxy + mxy); - myt += anchorx * (myx + myx) + anchory * (myy + myy); - rotate180(); - break; - case 3: - mxt += anchorx * (mxx + mxy) + anchory * (mxy - mxx); - myt += anchorx * (myx + myy) + anchory * (myy - myx); - rotate270(); - break; - } - if (mxt == 0.0 && myt == 0.0) { - state &= ~APPLY_TRANSLATE; - if (type != TYPE_UNKNOWN) { - type &= ~TYPE_TRANSLATION; - } - } else { - state |= APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - } - - @Override - public void restoreTransform(double mxx, double myx, double mxy, double myy, - double mxt, double myt) { - setTransform(mxx, myx, mxy, myy, mxt, myt); - } - - @Override - public void restoreTransform(double mxx, double mxy, double mxz, double mxt, - double myx, double myy, double myz, double myt, - double mzx, double mzy, double mzz, - double mzt) { - if (mxz != 0 || myz != 0 || mzx != 0 || mzy != 0 || mzz != 1 - || mzt != 0.0) { - degreeError(Degree.AFFINE_2D); - } - setTransform(mxx, myx, mxy, myy, mxt, myt); - } - - /** - * Concatenates this transform with a transform that rotates coordinates - * according to a rotation vector. All coordinates rotate about the origin - * by the same amount. The amount of rotation is such that coordinates along - * the former positive X axis will subsequently align with the vector - * pointing from the origin to the specified vector coordinates. If both - * vecx and vecy are 0.0, no additional rotation - * is added to this transform. This operation is equivalent to calling: - * - *
-     * rotate(Math.atan2(vecy, vecx));
-     * 
- * - * @param vecx - * the X coordinate of the rotation vector - * @param vecy - * the Y coordinate of the rotation vector - */ - public void rotate(double vecx, double vecy) { - if (vecy == 0.0) { - if (vecx < 0.0) { - rotate180(); - } - // If vecx > 0.0 - no rotation - // If vecx == 0.0 - undefined rotation - treat as no rotation - } else if (vecx == 0.0) { - if (vecy > 0.0) { - rotate90(); - } else { // vecy must be < 0.0 - rotate270(); - } - } else { - double len = Math.sqrt(vecx * vecx + vecy * vecy); - double sin = vecy / len; - double cos = vecx / len; - double M0, M1; - M0 = mxx; - M1 = mxy; - mxx = cos * M0 + sin * M1; - mxy = -sin * M0 + cos * M1; - M0 = myx; - M1 = myy; - myx = cos * M0 + sin * M1; - myy = -sin * M0 + cos * M1; - updateState2D(); - } - } - - /** - * Concatenates this transform with a transform that rotates coordinates - * around an anchor point. This operation is equivalent to translating the - * coordinates so that the anchor point is at the origin (S1), then rotating - * them about the new origin (S2), and finally translating so that the - * intermediate origin is restored to the coordinates of the original anchor - * point (S3). - *

- * This operation is equivalent to the following sequence of calls: - * - *

-     * translate(anchorx, anchory); // S3: final translation
-     * rotate(theta); // S2: rotate around anchor
-     * translate(-anchorx, -anchory); // S1: translate anchor to origin
-     * 
- * - * Rotating by a positive angle theta rotates points on the positive X axis - * toward the positive Y axis. Note also the discussion of - * Handling 90-Degree Rotations above. - * - * @param theta - * the angle of rotation measured in radians - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void rotate(double theta, double anchorx, double anchory) { - // REMIND: Simple for now - optimize later - translate(anchorx, anchory); - rotate(theta); - translate(-anchorx, -anchory); - } - - /** - * Concatenates this transform with a transform that rotates coordinates - * around an anchor point according to a rotation vector. All coordinates - * rotate about the specified anchor coordinates by the same amount. The - * amount of rotation is such that coordinates along the former positive X - * axis will subsequently align with the vector pointing from the origin to - * the specified vector coordinates. If both vecx and - * vecy are 0.0, the transform is not modified in any way. This - * method is equivalent to calling: - * - *
-     * rotate(Math.atan2(vecy, vecx), anchorx, anchory);
-     * 
- * - * @param vecx - * the X coordinate of the rotation vector - * @param vecy - * the Y coordinate of the rotation vector - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void rotate(double vecx, double vecy, double anchorx, - double anchory) { - // REMIND: Simple for now - optimize later - translate(anchorx, anchory); - rotate(vecx, vecy); - translate(-anchorx, -anchory); - } - - /** - * Sets this transform to a rotation transformation that rotates coordinates - * by the specified number of quadrants. This operation is equivalent to - * calling: - * - *
-     * setToRotation(numquadrants * Math.PI / 2.0);
-     * 
- * - * Rotating by a positive number of quadrants rotates points on the positive - * X axis toward the positive Y axis. - * - * @param numquadrants - * the number of 90 degree arcs to rotate by - */ - public void setToQuadrantRotation(int numquadrants) { - switch (numquadrants & 3) { - case 0: - mxx = 1.0; - myx = 0.0; - mxy = 0.0; - myy = 1.0; - mxt = 0.0; - myt = 0.0; - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - break; - case 1: - mxx = 0.0; - myx = 1.0; - mxy = -1.0; - myy = 0.0; - mxt = 0.0; - myt = 0.0; - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - break; - case 2: - mxx = -1.0; - myx = 0.0; - mxy = 0.0; - myy = -1.0; - mxt = 0.0; - myt = 0.0; - state = APPLY_SCALE; - type = TYPE_QUADRANT_ROTATION; - break; - case 3: - mxx = 0.0; - myx = -1.0; - mxy = 1.0; - myy = 0.0; - mxt = 0.0; - myt = 0.0; - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - break; - } - } - - /** - * Sets this transform to a translated rotation transformation that rotates - * coordinates by the specified number of quadrants around the specified - * anchor point. This operation is equivalent to calling: - * - *
-     * setToRotation(numquadrants * Math.PI / 2.0, anchorx, anchory);
-     * 
- * - * Rotating by a positive number of quadrants rotates points on the positive - * X axis toward the positive Y axis. - * - * @param numquadrants - * the number of 90 degree arcs to rotate by - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void setToQuadrantRotation(int numquadrants, double anchorx, - double anchory) { - switch (numquadrants & 3) { - case 0: - mxx = 1.0; - myx = 0.0; - mxy = 0.0; - myy = 1.0; - mxt = 0.0; - myt = 0.0; - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - break; - case 1: - mxx = 0.0; - myx = 1.0; - mxy = -1.0; - myy = 0.0; - mxt = anchorx + anchory; - myt = anchory - anchorx; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - } else { - state = APPLY_SHEAR | APPLY_TRANSLATE; - type = TYPE_QUADRANT_ROTATION | TYPE_TRANSLATION; - } - break; - case 2: - mxx = -1.0; - myx = 0.0; - mxy = 0.0; - myy = -1.0; - mxt = anchorx + anchorx; - myt = anchory + anchory; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SCALE; - type = TYPE_QUADRANT_ROTATION; - } else { - state = APPLY_SCALE | APPLY_TRANSLATE; - type = TYPE_QUADRANT_ROTATION | TYPE_TRANSLATION; - } - break; - case 3: - mxx = 0.0; - myx = -1.0; - mxy = 1.0; - myy = 0.0; - mxt = anchorx - anchory; - myt = anchory + anchorx; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - } else { - state = APPLY_SHEAR | APPLY_TRANSLATE; - type = TYPE_QUADRANT_ROTATION | TYPE_TRANSLATION; - } - break; - } - } - - /** - * Sets this transform to a rotation transformation. The matrix representing - * this transform becomes: - * - *
-     *      [   cos(theta)    -sin(theta)    0   ]
-     *      [   sin(theta)     cos(theta)    0   ]
-     *      [       0              0         1   ]
-     * 
- * - * Rotating by a positive angle theta rotates points on the positive X axis - * toward the positive Y axis. Note also the discussion of - * Handling 90-Degree Rotations above. - * - * @param theta - * the angle of rotation measured in radians - */ - public void setToRotation(double theta) { - double sin = Math.sin(theta); - double cos; - if (sin == 1.0 || sin == -1.0) { - cos = 0.0; - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - } else { - cos = Math.cos(theta); - if (cos == -1.0) { - sin = 0.0; - state = APPLY_SCALE; - type = TYPE_QUADRANT_ROTATION; - } else if (cos == 1.0) { - sin = 0.0; - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } else { - state = APPLY_SHEAR | APPLY_SCALE; - type = TYPE_GENERAL_ROTATION; - } - } - mxx = cos; - myx = sin; - mxy = -sin; - myy = cos; - mxt = 0.0; - myt = 0.0; - } - - /** - * Sets this transform to a rotation transformation that rotates coordinates - * according to a rotation vector. All coordinates rotate about the origin - * by the same amount. The amount of rotation is such that coordinates along - * the former positive X axis will subsequently align with the vector - * pointing from the origin to the specified vector coordinates. If both - * vecx and vecy are 0.0, the transform is set to - * an identity transform. This operation is equivalent to calling: - * - *
-     * setToRotation(Math.atan2(vecy, vecx));
-     * 
- * - * @param vecx - * the X coordinate of the rotation vector - * @param vecy - * the Y coordinate of the rotation vector - */ - public void setToRotation(double vecx, double vecy) { - double sin, cos; - if (vecy == 0) { - sin = 0.0; - if (vecx < 0.0) { - cos = -1.0; - state = APPLY_SCALE; - type = TYPE_QUADRANT_ROTATION; - } else { - cos = 1.0; - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - } else if (vecx == 0) { - cos = 0.0; - sin = (vecy > 0.0) ? 1.0 : -1.0; - state = APPLY_SHEAR; - type = TYPE_QUADRANT_ROTATION; - } else { - double len = Math.sqrt(vecx * vecx + vecy * vecy); - cos = vecx / len; - sin = vecy / len; - state = APPLY_SHEAR | APPLY_SCALE; - type = TYPE_GENERAL_ROTATION; - } - mxx = cos; - myx = sin; - mxy = -sin; - myy = cos; - mxt = 0.0; - myt = 0.0; - } - - /** - * Sets this transform to a translated rotation transformation. This - * operation is equivalent to translating the coordinates so that the anchor - * point is at the origin (S1), then rotating them about the new origin - * (S2), and finally translating so that the intermediate origin is restored - * to the coordinates of the original anchor point (S3). - *

- * This operation is equivalent to the following sequence of calls: - * - *

-     * setToTranslation(anchorx, anchory); // S3: final translation
-     * rotate(theta); // S2: rotate around anchor
-     * translate(-anchorx, -anchory); // S1: translate anchor to origin
-     * 
- * - * The matrix representing this transform becomes: - * - *
-     *      [   cos(theta)    -sin(theta)    x-x*cos+y*sin  ]
-     *      [   sin(theta)     cos(theta)    y-x*sin-y*cos  ]
-     *      [       0              0               1        ]
-     * 
- * - * Rotating by a positive angle theta rotates points on the positive X axis - * toward the positive Y axis. Note also the discussion of - * Handling 90-Degree Rotations above. - * - * @param theta - * the angle of rotation measured in radians - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void setToRotation(double theta, double anchorx, double anchory) { - setToRotation(theta); - double sin = myx; - double oneMinusCos = 1.0 - mxx; - mxt = anchorx * oneMinusCos + anchory * sin; - myt = anchory * oneMinusCos - anchorx * sin; - if (mxt != 0.0 || myt != 0.0) { - state |= APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - } - - /** - * Sets this transform to a rotation transformation that rotates coordinates - * around an anchor point according to a rotation vector. All coordinates - * rotate about the specified anchor coordinates by the same amount. The - * amount of rotation is such that coordinates along the former positive X - * axis will subsequently align with the vector pointing from the origin to - * the specified vector coordinates. If both vecx and - * vecy are 0.0, the transform is set to an identity transform. - * This operation is equivalent to calling: - * - *
-     * setToTranslation(Math.atan2(vecy, vecx), anchorx, anchory);
-     * 
- * - * @param vecx - * the X coordinate of the rotation vector - * @param vecy - * the Y coordinate of the rotation vector - * @param anchorx - * the X coordinate of the rotation anchor point - * @param anchory - * the Y coordinate of the rotation anchor point - */ - public void setToRotation(double vecx, double vecy, double anchorx, - double anchory) { - setToRotation(vecx, vecy); - double sin = myx; - double oneMinusCos = 1.0 - mxx; - mxt = anchorx * oneMinusCos + anchory * sin; - myt = anchory * oneMinusCos - anchorx * sin; - if (mxt != 0.0 || myt != 0.0) { - state |= APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - } - - /** - * Sets this transform to a scaling transformation. The matrix representing - * this transform becomes: - * - *
-     *      [   sx   0    0   ]
-     *      [   0    sy   0   ]
-     *      [   0    0    1   ]
-     * 
- * - * @param sx - * the factor by which coordinates are scaled along the X axis - * direction - * @param sy - * the factor by which coordinates are scaled along the Y axis - * direction - */ - public void setToScale(double sx, double sy) { - mxx = sx; - myx = 0.0; - mxy = 0.0; - myy = sy; - mxt = 0.0; - myt = 0.0; - if (sx != 1.0 || sy != 1.0) { - state = APPLY_SCALE; - type = TYPE_UNKNOWN; - } else { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - } - - /** - * Sets this transform to a translation transformation. The matrix - * representing this transform becomes: - * - *
-     *      [   1    0    tx  ]
-     *      [   0    1    ty  ]
-     *      [   0    0    1   ]
-     * 
- * - * @param tx - * the distance by which coordinates are translated in the X axis - * direction - * @param ty - * the distance by which coordinates are translated in the Y axis - * direction - */ - public void setToTranslation(double tx, double ty) { - mxx = 1.0; - myx = 0.0; - mxy = 0.0; - myy = 1.0; - mxt = tx; - myt = ty; - if (tx != 0.0 || ty != 0.0) { - state = APPLY_TRANSLATE; - type = TYPE_TRANSLATION; - } else { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - } - - /** - * Sets this transform to a copy of the transform in the specified - * BaseTransform object. - * - * @param Tx - * the BaseTransform object from which to copy the - * transform - */ - @Override - public void setTransform(BaseTransform Tx) { - switch (Tx.getDegree()) { - case IDENTITY: - setToIdentity(); - break; - case TRANSLATE_2D: - setToTranslation(Tx.getMxt(), Tx.getMyt()); - break; - default: - if (Tx.getType() > TYPE_AFFINE2D_MASK) { - System.out.println(Tx + " is " + Tx.getType()); - System.out.print(" " + Tx.getMxx()); - System.out.print(", " + Tx.getMxy()); - System.out.print(", " + Tx.getMxz()); - System.out.print(", " + Tx.getMxt()); - System.out.println(); - System.out.print(" " + Tx.getMyx()); - System.out.print(", " + Tx.getMyy()); - System.out.print(", " + Tx.getMyz()); - System.out.print(", " + Tx.getMyt()); - System.out.println(); - System.out.print(" " + Tx.getMzx()); - System.out.print(", " + Tx.getMzy()); - System.out.print(", " + Tx.getMzz()); - System.out.print(", " + Tx.getMzt()); - System.out.println(); - // TODO: Should this be thrown before we modify anything? - // (RT-26801) - degreeError(Degree.AFFINE_2D); - } - /* No Break */ - case AFFINE_2D: - this.mxx = Tx.getMxx(); - this.myx = Tx.getMyx(); - this.mxy = Tx.getMxy(); - this.myy = Tx.getMyy(); - this.mxt = Tx.getMxt(); - this.myt = Tx.getMyt(); - if (Tx instanceof AffineBase) { - this.state = ((AffineBase) Tx).state; - this.type = ((AffineBase) Tx).type; - } else { - updateState2D(); - } - break; - } - } - - /** - * Returns a String that represents the value of this - * {@link Object}. - * - * @return a String representing the value of this - * Object. - */ - @Override - public String toString() { - return ("Affine2D[[" + _matround(mxx) + ", " + _matround(mxy) + ", " - + _matround(mxt) + "], [" + _matround(myx) + ", " - + _matround(myy) + ", " + _matround(myt) + "]]"); - } - - /** - * Transforms an array of point objects by this transform. If any element of - * the ptDst array is null, a new - * Point2D object is allocated and stored into that element - * before storing the results of the transformation. - *

- * Note that this method does not take any precautions to avoid problems - * caused by storing results into Point2D objects that will be - * used as the source for calculations further down the source array. This - * method does guarantee that if a specified Point2D object is - * both the source and destination for the same single point transform - * operation then the results will not be stored until the calculations are - * complete to avoid storing the results on top of the operands. If, - * however, the destination Point2D object for one operation is - * the same object as the source Point2D object for another - * operation further down the source array then the original coordinates in - * that point are overwritten before they can be converted. - * - * @param ptSrc - * the array containing the source point objects - * @param ptDst - * the array into which the transform point objects are returned - * @param srcOff - * the offset to the first point object to be transformed in the - * source array - * @param dstOff - * the offset to the location of the first transformed point - * object that is stored in the destination array - * @param numPts - * the number of point objects to be transformed - */ - public void transform(Point2D[] ptSrc, int srcOff, Point2D[] ptDst, - int dstOff, int numPts) { - int mystate = this.state; - while (--numPts >= 0) { - // Copy source coords into local variables in case src == dst - Point2D src = ptSrc[srcOff++]; - double x = src.x; - double y = src.y; - Point2D dst = ptDst[dstOff++]; - if (dst == null) { - dst = new Point2D(); - ptDst[dstOff - 1] = dst; - } - switch (mystate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - dst.setLocation((float) (x * mxx + y * mxy + mxt), - (float) (x * myx + y * myy + myt)); - break; - case (APPLY_SHEAR | APPLY_SCALE): - dst.setLocation((float) (x * mxx + y * mxy), - (float) (x * myx + y * myy)); - break; - case (APPLY_SHEAR | APPLY_TRANSLATE): - dst.setLocation((float) (y * mxy + mxt), - (float) (x * myx + myt)); - break; - case (APPLY_SHEAR): - dst.setLocation((float) (y * mxy), (float) (x * myx)); - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - dst.setLocation((float) (x * mxx + mxt), - (float) (y * myy + myt)); - break; - case (APPLY_SCALE): - dst.setLocation((float) (x * mxx), (float) (y * myy)); - break; - case (APPLY_TRANSLATE): - dst.setLocation((float) (x + mxt), (float) (y + myt)); - break; - case (APPLY_IDENTITY): - dst.setLocation((float) x, (float) y); - break; - } - } - - /* NOTREACHED */ - } - - @Override - protected void reset3Delements() { - /* NOP for Affine2D */ } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine3D.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine3D.java deleted file mode 100644 index 4561f48..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Affine3D.java +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Point2D; -import com.javafx.experiments.utils3d.geom.Rectangle; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public class Affine3D extends AffineBase { - static boolean almostOne(double a) { - return ((a < 1 + EPSILON_ABSOLUTE) && (a > 1 - EPSILON_ABSOLUTE)); - } - - // Round values to sane precision for printing - // Note that Math.sin(Math.PI) has an error of about 10^-16 - private static double _matround(double matval) { - return Math.rint(matval * 1E15) / 1E15; - } - - private double mxz; - private double myz; - private double mzt; - private double mzx; - - private double mzy; - - private double mzz; - - public Affine3D() { - mxx = myy = mzz = 1.0; - // mxy = mxz = mxt = 0.0; /* Not needed. */ - // myx = myz = myt = 0.0; /* Not needed. */ - // mzx = mzy = mzt = 0.0; /* Not needed. */ - // type = TYPE_IDENTITY; /* Not needed. */ - } - - public Affine3D(Affine3D other) { - this.mxx = other.mxx; - this.mxy = other.mxy; - this.mxz = other.mxz; - this.mxt = other.mxt; - - this.myx = other.myx; - this.myy = other.myy; - this.myz = other.myz; - this.myt = other.myt; - - this.mzx = other.mzx; - this.mzy = other.mzy; - this.mzz = other.mzz; - this.mzt = other.mzt; - - this.state = other.state; - this.type = other.type; - } - - public Affine3D(BaseTransform transform) { - setTransform(transform); - } - - public Affine3D(double mxx, double mxy, double mxz, double mxt, double myx, - double myy, double myz, double myt, double mzx, double mzy, - double mzz, double mzt) { - this.mxx = mxx; - this.mxy = mxy; - this.mxz = mxz; - this.mxt = mxt; - - this.myx = myx; - this.myy = myy; - this.myz = myz; - this.myt = myt; - - this.mzx = mzx; - this.mzy = mzy; - this.mzz = mzz; - this.mzt = mzt; - - updateState(); - } - - @Override - public void concatenate(BaseTransform transform) { - switch (transform.getDegree()) { - case IDENTITY: - return; - case TRANSLATE_2D: - translate(transform.getMxt(), transform.getMyt()); - return; - case TRANSLATE_3D: - translate(transform.getMxt(), transform.getMyt(), - transform.getMzt()); - return; - case AFFINE_3D: - if (!transform.is2D()) { - break; - } - /* No Break */ - case AFFINE_2D: - if ((state & APPLY_3D) == 0) { - super.concatenate(transform); - return; - } - break; - } - double Txx = transform.getMxx(); - double Txy = transform.getMxy(); - double Txz = transform.getMxz(); - double Txt = transform.getMxt(); - double Tyx = transform.getMyx(); - double Tyy = transform.getMyy(); - double Tyz = transform.getMyz(); - double Tyt = transform.getMyt(); - double Tzx = transform.getMzx(); - double Tzy = transform.getMzy(); - double Tzz = transform.getMzz(); - double Tzt = transform.getMzt(); - double rxx = (mxx * Txx + mxy * Tyx + mxz * Tzx /* + mxt * 0.0 */); - double rxy = (mxx * Txy + mxy * Tyy + mxz * Tzy /* + mxt * 0.0 */); - double rxz = (mxx * Txz + mxy * Tyz + mxz * Tzz /* + mxt * 0.0 */); - double rxt = (mxx * Txt + mxy * Tyt + mxz * Tzt + mxt /* * 1.0 */); - double ryx = (myx * Txx + myy * Tyx + myz * Tzx /* + myt * 0.0 */); - double ryy = (myx * Txy + myy * Tyy + myz * Tzy /* + myt * 0.0 */); - double ryz = (myx * Txz + myy * Tyz + myz * Tzz /* + myt * 0.0 */); - double ryt = (myx * Txt + myy * Tyt + myz * Tzt + myt /* * 1.0 */); - double rzx = (mzx * Txx + mzy * Tyx + mzz * Tzx /* + mzt * 0.0 */); - double rzy = (mzx * Txy + mzy * Tyy + mzz * Tzy /* + mzt * 0.0 */); - double rzz = (mzx * Txz + mzy * Tyz + mzz * Tzz /* + mzt * 0.0 */); - double rzt = (mzx * Txt + mzy * Tyt + mzz * Tzt + mzt /* * 1.0 */); - this.mxx = rxx; - this.mxy = rxy; - this.mxz = rxz; - this.mxt = rxt; - this.myx = ryx; - this.myy = ryy; - this.myz = ryz; - this.myt = ryt; - this.mzx = rzx; - this.mzy = rzy; - this.mzz = rzz; - this.mzt = rzt; - updateState(); - } - - public void concatenate(double Txx, double Txy, double Txz, double Txt, - double Tyx, double Tyy, double Tyz, double Tyt, - double Tzx, double Tzy, double Tzz, double Tzt) { - double rxx = (mxx * Txx + mxy * Tyx + mxz * Tzx /* + mxt * 0.0 */); - double rxy = (mxx * Txy + mxy * Tyy + mxz * Tzy /* + mxt * 0.0 */); - double rxz = (mxx * Txz + mxy * Tyz + mxz * Tzz /* + mxt * 0.0 */); - double rxt = (mxx * Txt + mxy * Tyt + mxz * Tzt + mxt /* * 1.0 */); - double ryx = (myx * Txx + myy * Tyx + myz * Tzx /* + myt * 0.0 */); - double ryy = (myx * Txy + myy * Tyy + myz * Tzy /* + myt * 0.0 */); - double ryz = (myx * Txz + myy * Tyz + myz * Tzz /* + myt * 0.0 */); - double ryt = (myx * Txt + myy * Tyt + myz * Tzt + myt /* * 1.0 */); - double rzx = (mzx * Txx + mzy * Tyx + mzz * Tzx /* + mzt * 0.0 */); - double rzy = (mzx * Txy + mzy * Tyy + mzz * Tzy /* + mzt * 0.0 */); - double rzz = (mzx * Txz + mzy * Tyz + mzz * Tzz /* + mzt * 0.0 */); - double rzt = (mzx * Txt + mzy * Tyt + mzz * Tzt + mzt /* * 1.0 */); - this.mxx = rxx; - this.mxy = rxy; - this.mxz = rxz; - this.mxt = rxt; - this.myx = ryx; - this.myy = ryy; - this.myz = ryz; - this.myt = ryt; - this.mzx = rzx; - this.mzy = rzy; - this.mzz = rzz; - this.mzt = rzt; - updateState(); - } - - @Override - public BaseTransform copy() { - return new Affine3D(this); - } - - @Override - public BaseTransform createInverse() throws NoninvertibleTransformException { - BaseTransform t = copy(); - t.invert(); - return t; - } - - @Override - public Vec3d deltaTransform(Vec3d src, Vec3d dst) { - if ((state & APPLY_3D) == 0) { - return super.deltaTransform(src, dst); - } - if (dst == null) { - dst = new Vec3d(); - } - double x = src.x; - double y = src.y; - double z = src.z; - dst.x = mxx * x + mxy * y + mxz * z; - dst.y = myx * x + myy * y + myz * z; - dst.z = mzx * x + mzy * y + mzz * z; - return dst; - } - - @Override - public Affine3D deriveWithConcatenation(BaseTransform transform) { - concatenate(transform); - return this; - } - - @Override - public Affine3D deriveWithConcatenation(double Txx, double Tyx, double Txy, - double Tyy, double Txt, - double Tyt) { - double rxx = (mxx * Txx + mxy * Tyx /* + mxz * 0.0 + mxt * 0.0 */); - double rxy = (mxx * Txy + mxy * Tyy /* + mxz * 0.0 + mxt * 0.0 */); - // double rxz = (mxz /* * 1.0 + mxx * 0.0 + mxy * 0.0 + mxt * 0.0 */); - double rxt = (mxx * Txt + mxy * Tyt + mxt /* + mxz * 0.0 * 1.0 */); - double ryx = (myx * Txx + myy * Tyx /* + myz * 0.0 + myt * 0.0 */); - double ryy = (myx * Txy + myy * Tyy /* + myz * 0.0 + myt * 0.0 */); - // double ryz = (myz /* * 1.0 + myx * 0.0 + myy * 0.0 + myt * 0.0 */); - double ryt = (myx * Txt + myy * Tyt + myt /* * 1.0 + myz * 0.0 */); - double rzx = (mzx * Txx + mzy * Tyx /* + mzz * 0.0 + mzt * 0.0 */); - double rzy = (mzx * Txy + mzy * Tyy /* + mzz * 0.0 + mzt * 0.0 */); - // double rzz = (mzz /* * 1.0 + mzx * 0.0 + mzy * 0.0 + mzt * 0.0 */); - double rzt = (mzx * Txt + mzy * Tyt + mzt /* * 1.0 + mzz * 0.0 */); - this.mxx = rxx; - this.mxy = rxy; - // this.mxz = rxz; // == mxz anyway - this.mxt = rxt; - this.myx = ryx; - this.myy = ryy; - // this.myz = ryz; // == myz anyway - this.myt = ryt; - this.mzx = rzx; - this.mzy = rzy; - // this.mzz = rzz; // == mzz anyway - this.mzt = rzt; - updateState(); - return this; - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double mxy, - double mxz, double mxt, - double myx, double myy, - double myz, double myt, - double mzx, double mzy, - double mzz, double mzt) { - concatenate(mxx, mxy, mxz, mxt, myx, myy, myz, myt, mzx, mzy, mzz, mzt); - return this; - } - - @Override - public Affine3D deriveWithNewTransform(BaseTransform tx) { - setTransform(tx); - return this; - } - - @Override - public Affine3D deriveWithPreConcatenation(BaseTransform transform) { - preConcatenate(transform); - return this; - } - - @Override - public Affine3D deriveWithPreTranslation(double mxt, double myt) { - preTranslate(mxt, myt, 0.0); - return this; - } - - @Override - public BaseTransform deriveWithRotation(double theta, double axisX, - double axisY, double axisZ) { - rotate(theta, axisX, axisY, axisZ); - return this; - } - - @Override - public BaseTransform deriveWithScale(double mxx, double myy, double mzz) { - scale(mxx, myy, mzz); - return this; - } - - @Override - public Affine3D deriveWithTranslation(double tx, double ty) { - translate(tx, ty, 0.0); - return this; - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt, - double mzt) { - translate(mxt, myt, mzt); - return this; - } - - @Override - public Degree getDegree() { - return Degree.AFFINE_3D; - } - - @Override - public double getDeterminant() { - if ((state & APPLY_3D) == 0) { - return super.getDeterminant(); - } - // D=a11{a22a33-a32a23} - // +a12{a23a31-a33a21} - // +a13{a21a32-a31a22} - return (mxx * (myy * mzz - mzy * myz) + mxy * (myz * mzx - mzz * myx) - + mxz * (myx * mzy - mzx * myy)); - } - - @Override - public double getMxz() { - return mxz; - } - - @Override - public double getMyz() { - return myz; - } - - @Override - public double getMzt() { - return mzt; - } - - @Override - public double getMzx() { - return mzx; - } - - @Override - public double getMzy() { - return mzy; - } - - @Override - public double getMzz() { - return mzz; - } - - @Override - public void inverseDeltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int numPts) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - super.inverseDeltaTransform(srcPts, srcOff, dstPts, dstOff, numPts); - } else { - // TODO: Optimize... (RT-26800) - createInverse().deltaTransform(srcPts, srcOff, dstPts, dstOff, - numPts); - } - } - - @Override - public Vec3d inverseDeltaTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - return super.inverseDeltaTransform(src, dst); - } else { - // TODO: Optimize... (RT-26800) - return createInverse().deltaTransform(src, dst); - } - } - - @Override - public BaseBounds inverseTransform(BaseBounds bounds, - BaseBounds result) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - result = super.inverseTransform(bounds, result); - } else { - // TODO: Optimize... (RT-26800) - result = createInverse().transform(bounds, result); - } - return result; - } - - @Override - public void inverseTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, - int numPts) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - super.inverseTransform(srcPts, srcOff, dstPts, dstOff, numPts); - } else { - // TODO: Optimize... (RT-26800) - createInverse().transform(srcPts, srcOff, dstPts, dstOff, numPts); - } - } - - @Override - public void inverseTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, - int numPts) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - super.inverseTransform(srcPts, srcOff, dstPts, dstOff, numPts); - } else { - // TODO: Optimize... (RT-26800) - createInverse().transform(srcPts, srcOff, dstPts, dstOff, numPts); - } - } - - @Override - public Point2D inverseTransform(Point2D src, - Point2D dst) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - return super.inverseTransform(src, dst); - } else { - // TODO: Optimize... (RT-26800) - return createInverse().transform(src, dst); - } - } - - @Override - public void inverseTransform(Rectangle bounds, - Rectangle result) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - super.inverseTransform(bounds, result); - } else { - // TODO: Optimize... (RT-26800) - createInverse().transform(bounds, result); - } - } - - @Override - public Vec3d inverseTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - return super.inverseTransform(src, dst); - } else { - // TODO: Optimize... (RT-26800) - return createInverse().transform(src, dst); - } - } - - @Override - public void invert() throws NoninvertibleTransformException { - if ((state & APPLY_3D) == 0) { - super.invert(); - return; - } - // InvM = Transpose(Cofactor(M)) / det(M) - // Cofactor(M) = matrix of cofactors(0..3,0..3) - // cofactor(r,c) = (-1 if r+c is odd) * minor(r,c) - // minor(r,c) = det(M with row r and col c removed) - // For an Affine3D matrix, minor(r, 3) is {0, 0, 0, det} - // which generates {0, 0, 0, 1} and so can be ignored. - - // TODO: Inlining the minor calculations should allow them - // to be simplified... (RT-26800) - double cxx = minor(0, 0); - double cyx = -minor(0, 1); - double czx = minor(0, 2); - double cxy = -minor(1, 0); - double cyy = minor(1, 1); - double czy = -minor(1, 2); - double cxz = minor(2, 0); - double cyz = -minor(2, 1); - double czz = minor(2, 2); - double cxt = -minor(3, 0); - double cyt = minor(3, 1); - double czt = -minor(3, 2); - double det = getDeterminant(); - mxx = cxx / det; - mxy = cxy / det; - mxz = cxz / det; - mxt = cxt / det; - myx = cyx / det; - myy = cyy / det; - myz = cyz / det; - myt = cyt / det; - mzx = czx / det; - mzy = czy / det; - mzz = czz / det; - mzt = czt / det; - updateState(); - } - - /** - * Sets this transform to a viewing transform computed from the specified - * eye point, center point, and up vector. The resulting transform can be - * used as the view transform in a 3D camera. - * - * @param eye - * the eye point - * @param center - * the center point - * @param up - * the up vector - * @return this transform - */ - public Affine3D lookAt(Vec3d eye, Vec3d center, Vec3d up) { - double forwardx, forwardy, forwardz, invMag; - double upx, upy, upz; - double sidex, sidey, sidez; - - forwardx = eye.x - center.x; - forwardy = eye.y - center.y; - forwardz = eye.z - center.z; - - invMag = 1.0 / Math.sqrt(forwardx * forwardx + forwardy * forwardy - + forwardz * forwardz); - forwardx = forwardx * invMag; - forwardy = forwardy * invMag; - forwardz = forwardz * invMag; - - invMag = 1.0 / Math.sqrt(up.x * up.x + up.y * up.y + up.z * up.z); - upx = up.x * invMag; - upy = up.y * invMag; - upz = up.z * invMag; - - // side = Up cross forward - sidex = upy * forwardz - forwardy * upz; - sidey = upz * forwardx - upx * forwardz; - sidez = upx * forwardy - upy * forwardx; - - invMag = 1.0 / Math.sqrt(sidex * sidex + sidey * sidey + sidez * sidez); - sidex *= invMag; - sidey *= invMag; - sidez *= invMag; - - // recompute up = forward cross side - upx = forwardy * sidez - sidey * forwardz; - upy = forwardz * sidex - forwardx * sidez; - upz = forwardx * sidey - forwardy * sidex; - - // transpose because we calculated the inverse of what we want - mxx = sidex; - mxy = sidey; - mxz = sidez; - - myx = upx; - myy = upy; - myz = upz; - - mzx = forwardx; - mzy = forwardy; - mzz = forwardz; - - mxt = -eye.x * mxx + -eye.y * mxy + -eye.z * mxz; - myt = -eye.x * myx + -eye.y * myy + -eye.z * myz; - mzt = -eye.x * mzx + -eye.y * mzy + -eye.z * mzz; - - updateState(); - return this; - } - - public void preConcatenate(BaseTransform transform) { - switch (transform.getDegree()) { - case IDENTITY: - return; - case TRANSLATE_2D: - preTranslate(transform.getMxt(), transform.getMyt(), 0.0); - return; - case TRANSLATE_3D: - preTranslate(transform.getMxt(), transform.getMyt(), - transform.getMzt()); - return; - default: - break; - } - double Txx = transform.getMxx(); - double Txy = transform.getMxy(); - double Txz = transform.getMxz(); - double Txt = transform.getMxt(); - double Tyx = transform.getMyx(); - double Tyy = transform.getMyy(); - double Tyz = transform.getMyz(); - double Tyt = transform.getMyt(); - double Tzx = transform.getMzx(); - double Tzy = transform.getMzy(); - double Tzz = transform.getMzz(); - double Tzt = transform.getMzt(); - double rxx = (Txx * mxx + Txy * myx + Txz * mzx /* + Txt * 0.0 */); - double rxy = (Txx * mxy + Txy * myy + Txz * mzy /* + Txt * 0.0 */); - double rxz = (Txx * mxz + Txy * myz + Txz * mzz /* + Txt * 0.0 */); - double rxt = (Txx * mxt + Txy * myt + Txz * mzt + Txt /* * 1.0 */); - double ryx = (Tyx * mxx + Tyy * myx + Tyz * mzx /* + Tyt * 0.0 */); - double ryy = (Tyx * mxy + Tyy * myy + Tyz * mzy /* + Tyt * 0.0 */); - double ryz = (Tyx * mxz + Tyy * myz + Tyz * mzz /* + Tyt * 0.0 */); - double ryt = (Tyx * mxt + Tyy * myt + Tyz * mzt + Tyt /* * 1.0 */); - double rzx = (Tzx * mxx + Tzy * myx + Tzz * mzx /* + Tzt * 0.0 */); - double rzy = (Tzx * mxy + Tzy * myy + Tzz * mzy /* + Tzt * 0.0 */); - double rzz = (Tzx * mxz + Tzy * myz + Tzz * mzz /* + Tzt * 0.0 */); - double rzt = (Tzx * mxt + Tzy * myt + Tzz * mzt + Tzt /* * 1.0 */); - this.mxx = rxx; - this.mxy = rxy; - this.mxz = rxz; - this.mxt = rxt; - this.myx = ryx; - this.myy = ryy; - this.myz = ryz; - this.myt = ryt; - this.mzx = rzx; - this.mzy = rzy; - this.mzz = rzz; - this.mzt = rzt; - updateState(); - } - - public void preTranslate(double mxt, double myt, double mzt) { - this.mxt += mxt; - this.myt += myt; - this.mzt += mzt; - int clearflags = 0; - int setflags = 0; - if (this.mzt == 0.0) { - if ((state & APPLY_3D) != 0) { - // Might have become non-3D... - updateState(); - return; - } - } else { - state |= APPLY_3D; - setflags = TYPE_AFFINE_3D; - } - if (this.mxt == 0.0 && this.myt == 0.0) { - state &= ~APPLY_TRANSLATE; - clearflags = TYPE_TRANSLATION; - } else { - state |= APPLY_TRANSLATE; - setflags |= TYPE_TRANSLATION; - } - if (type != TYPE_UNKNOWN) { - type = ((type & ~clearflags) | setflags); - } - } - - @Override - public void restoreTransform(double mxx, double myx, double mxy, double myy, - double mxt, double myt) { - throw new InternalError("must use Affine3D restore method " - + "to prevent loss of information"); - } - - @Override - public void restoreTransform(double mxx, double mxy, double mxz, double mxt, - double myx, double myy, double myz, double myt, - double mzx, double mzy, double mzz, - double mzt) { - this.mxx = mxx; - this.mxy = mxy; - this.mxz = mxz; - this.mxt = mxt; - - this.myx = myx; - this.myy = myy; - this.myz = myz; - this.myt = myt; - - this.mzx = mzx; - this.mzy = mzy; - this.mzz = mzz; - this.mzt = mzt; - - updateState(); - } - - @Override - public void rotate(double theta) { - if ((state & APPLY_3D) == 0) { - super.rotate(theta); - } else { - rotate(theta, 0, 0, 1); - } - } - - public void rotate(double theta, double axisX, double axisY, double axisZ) { - if ((state & APPLY_3D) == 0 && almostZero(axisX) && almostZero(axisY)) { - if (axisZ > 0) { - super.rotate(theta); - } else if (axisZ < 0) { - super.rotate(-theta); - } // else rotating about zero vector - NOP - return; - } - double mag = Math.sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ); - - if (almostZero(mag)) { - return; - } - mag = 1.0 / mag; - double ax = axisX * mag; - double ay = axisY * mag; - double az = axisZ * mag; - - double sinTheta = Math.sin(theta); - double cosTheta = Math.cos(theta); - double t = 1.0 - cosTheta; - - double xz = ax * az; - double xy = ax * ay; - double yz = ay * az; - - double Txx = t * ax * ax + cosTheta; - double Txy = t * xy - sinTheta * az; - double Txz = t * xz + sinTheta * ay; - - double Tyx = t * xy + sinTheta * az; - double Tyy = t * ay * ay + cosTheta; - double Tyz = t * yz - sinTheta * ax; - - double Tzx = t * xz - sinTheta * ay; - double Tzy = t * yz + sinTheta * ax; - double Tzz = t * az * az + cosTheta; - - double rxx = (mxx * Txx + mxy * Tyx + mxz * Tzx /* + mxt * 0.0 */); - double rxy = (mxx * Txy + mxy * Tyy + mxz * Tzy /* + mxt * 0.0 */); - double rxz = (mxx * Txz + mxy * Tyz + mxz * Tzz /* + mxt * 0.0 */); - double ryx = (myx * Txx + myy * Tyx + myz * Tzx /* + myt * 0.0 */); - double ryy = (myx * Txy + myy * Tyy + myz * Tzy /* + myt * 0.0 */); - double ryz = (myx * Txz + myy * Tyz + myz * Tzz /* + myt * 0.0 */); - double rzx = (mzx * Txx + mzy * Tyx + mzz * Tzx /* + mzt * 0.0 */); - double rzy = (mzx * Txy + mzy * Tyy + mzz * Tzy /* + mzt * 0.0 */); - double rzz = (mzx * Txz + mzy * Tyz + mzz * Tzz /* + mzt * 0.0 */); - this.mxx = rxx; - this.mxy = rxy; - this.mxz = rxz; - this.myx = ryx; - this.myy = ryy; - this.myz = ryz; - this.mzx = rzx; - this.mzy = rzy; - this.mzz = rzz; - updateState(); - } - - @Override - public void scale(double sx, double sy) { - if ((state & APPLY_3D) == 0) { - super.scale(sx, sy); - } else { - scale(sx, sy, 1.0); - } - } - - public void scale(double sx, double sy, double sz) { - if ((state & APPLY_3D) == 0) { - super.scale(sx, sy); - if (sz != 1.0) { - this.mzz = sz; - state |= APPLY_3D; - if (type != TYPE_UNKNOWN) { - type |= TYPE_AFFINE_3D; - } - } - return; - } - this.mxx *= sx; - this.mxy *= sy; - this.mxz *= sz; - - this.myx *= sx; - this.myy *= sy; - this.myz *= sz; - - this.mzx *= sx; - this.mzy *= sy; - this.mzz *= sz; - - // TODO: Optimize the state... (RT-26800) - updateState(); - } - - public void setToRotation(double theta, double axisX, double axisY, - double axisZ) { - double mag = Math.sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ); - - if (almostZero(mag)) { - setToIdentity(); - return; - } - mag = 1.0 / mag; - double ax = axisX * mag; - double ay = axisY * mag; - double az = axisZ * mag; - - double sinTheta = Math.sin(theta); - double cosTheta = Math.cos(theta); - double t = 1.0 - cosTheta; - - double xz = ax * az; - double xy = ax * ay; - double yz = ay * az; - - this.mxx = t * ax * ax + cosTheta; - this.mxy = t * xy - sinTheta * az; - this.mxz = t * xz + sinTheta * ay; - this.mxt = 0.0; - - this.myx = t * xy + sinTheta * az; - this.myy = t * ay * ay + cosTheta; - this.myz = t * yz - sinTheta * ax; - this.myt = 0.0; - - this.mzx = t * xz - sinTheta * ay; - this.mzy = t * yz + sinTheta * ax; - this.mzz = t * az * az + cosTheta; - this.mzt = 0.0; - - updateState(); - } - - public void setToRotation(double theta, double axisX, double axisY, - double axisZ, double pivotX, double pivotY, - double pivotZ) { - setToRotation(theta, axisX, axisY, axisZ); - if (pivotX != 0.0 || pivotY != 0.0 || pivotZ != 0.0) { - preTranslate(pivotX, pivotY, pivotZ); - translate(-pivotX, -pivotY, -pivotZ); - } - } - - public void setToScale(double sx, double sy, double sz) { - this.mxx = sx; - this.mxy = 0.0; - this.mxz = 0.0; - this.mxt = 0.0; - - this.myx = 0.0; - this.myy = sy; - this.myz = 0.0; - this.myt = 0.0; - - this.mzx = 0.0; - this.mzy = 0.0; - this.mzz = sz; - this.mzt = 0.0; - - if (sz == 1.0) { - if (sx == 1.0 && sy == 1.0) { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } else { - state = APPLY_SCALE; - type = TYPE_UNKNOWN; - } - } else { - if (sx == 1.0 && sy == 1.0) { - state = APPLY_3D; - type = TYPE_AFFINE_3D; - } else { - state = APPLY_SCALE | APPLY_3D; - type = TYPE_UNKNOWN; - } - } - } - - public void setToTranslation(double tx, double ty, double tz) { - this.mxx = 1.0; - this.mxy = 0.0; - this.mxz = 0.0; - this.mxt = tx; - - this.myx = 0.0; - this.myy = 1.0; - this.myz = 0.0; - this.myt = ty; - - this.mzx = 0.0; - this.mzy = 0.0; - this.mzz = 1.0; - this.mzt = tz; - - if (tz == 0.0) { - if (tx == 0.0 && ty == 0.0) { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } else { - state = APPLY_TRANSLATE; - type = TYPE_TRANSLATION; - } - } else { - if (tx == 0.0 && ty == 0.0) { - state = APPLY_3D; - type = TYPE_AFFINE_3D; - } else { - state = APPLY_TRANSLATE | APPLY_3D; - type = TYPE_TRANSLATION | TYPE_AFFINE_3D; - } - } - } - - @Override - public void setTransform(BaseTransform transform) { - this.mxx = transform.getMxx(); - this.mxy = transform.getMxy(); - this.mxz = transform.getMxz(); - this.mxt = transform.getMxt(); - this.myx = transform.getMyx(); - this.myy = transform.getMyy(); - this.myz = transform.getMyz(); - this.myt = transform.getMyt(); - this.mzx = transform.getMzx(); - this.mzy = transform.getMzy(); - this.mzz = transform.getMzz(); - this.mzt = transform.getMzt(); - updateState(); - } - - public void setTransform(double mxx, double mxy, double mxz, double mxt, - double myx, double myy, double myz, double myt, - double mzx, double mzy, double mzz, double mzt) { - this.mxx = mxx; - this.mxy = mxy; - this.mxz = mxz; - this.mxt = mxt; - - this.myx = myx; - this.myy = myy; - this.myz = myz; - this.myt = myt; - - this.mzx = mzx; - this.mzy = mzy; - this.mzz = mzz; - this.mzt = mzt; - - updateState(); - } - - @Override - public void shear(double shx, double shy) { - if ((state & APPLY_3D) == 0) { - super.shear(shx, shy); - return; - } - double rxx = (mxx + mxy * shy); - double rxy = (mxy + mxx * shx); - double ryx = (myx + myy * shy); - double ryy = (myy + myx * shx); - double rzx = (mzx + mzy * shy); - double rzy = (mzy + mzx * shx); - this.mxx = rxx; - this.mxy = rxy; - this.myx = ryx; - this.myy = ryy; - this.mzx = rzx; - this.mzy = rzy; - updateState(); - } - - /** - * Returns a String that represents the value of this - * {@link Object}. - * - * @return a String representing the value of this - * Object. - */ - @Override - public String toString() { - return ("Affine3D[[" + _matround(mxx) + ", " + _matround(mxy) + ", " - + _matround(mxz) + ", " + _matround(mxt) + "], [" - + _matround(myx) + ", " + _matround(myy) + ", " + _matround(myz) - + ", " + _matround(myt) + "], [" + _matround(mzx) + ", " - + _matround(mzy) + ", " + _matround(mzz) + ", " + _matround(mzt) - + "]]"); - } - - @Override - public BaseBounds transform(BaseBounds src, BaseBounds dst) { - if ((state & APPLY_3D) == 0) { - return dst = super.transform(src, dst); - } - - switch (state) { - default: - /* NOBREAK */ - // TODO: Optimize these cases ... (RT-26800) - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR): - Vec3d tempV3d = new Vec3d(); - dst = TransformHelper.general3dBoundsTransform(this, src, dst, - tempV3d); - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinX() - * mxx + mxt), - (float) (src.getMinY() - * myy + myt), - (float) (src.getMinZ() - * mzz + mzt), - (float) (src.getMaxX() - * mxx + mxt), - (float) (src.getMaxY() - * myy + myt), - (float) (src.getMaxZ() - * mzz + mzt)); - break; - case (APPLY_SCALE): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinX() - * mxx), - (float) (src.getMinY() - * myy), - (float) (src.getMinZ() - * mzz), - (float) (src.getMaxX() - * mxx), - (float) (src.getMaxY() - * myy), - (float) (src.getMaxZ() - * mzz)); - break; - case (APPLY_TRANSLATE): - dst = dst.deriveWithNewBounds((float) (src.getMinX() + mxt), - (float) (src.getMinY() + myt), - (float) (src.getMinZ() + mzt), - (float) (src.getMaxX() + mxt), - (float) (src.getMaxY() + myt), - (float) (src.getMaxZ() + mzt)); - break; - case (APPLY_IDENTITY): - if (src != dst) { - dst = dst.deriveWithNewBounds(src); - } - - break; - } - return dst; - } - - @Override - public Vec3d transform(Vec3d src, Vec3d dst) { - if ((state & APPLY_3D) == 0) { - return super.transform(src, dst); - } - if (dst == null) { - dst = new Vec3d(); - } - double x = src.x; - double y = src.y; - double z = src.z; - dst.x = mxx * x + mxy * y + mxz * z + mxt; - dst.y = myx * x + myy * y + myz * z + myt; - dst.z = mzx * x + mzy * y + mzz * z + mzt; - return dst; - } - - @Override - public void translate(double tx, double ty) { - if ((state & APPLY_3D) == 0) { - super.translate(tx, ty); - } else { - translate(tx, ty, 0.0); - } - } - - public void translate(double tx, double ty, double tz) { - if ((state & APPLY_3D) == 0) { - super.translate(tx, ty); - if (tz != 0.0) { - this.mzt = tz; - state |= APPLY_3D; - if (type != TYPE_UNKNOWN) { - type |= TYPE_AFFINE_3D; - } - } - return; - } - this.mxt = tx * mxx + ty * mxy + tz * mxz + mxt; - this.myt = tx * myx + ty * myy + tz * myz + myt; - this.mzt = tx * mzx + ty * mzy + tz * mzz + mzt; - updateState(); - } - - @Override - protected void reset3Delements() { - this.mxz = 0.0; - this.myz = 0.0; - this.mzx = 0.0; - this.mzy = 0.0; - this.mzz = 1.0; - this.mzt = 0.0; - } - - @Override - protected void updateState() { - super.updateState(); - if (!almostZero(mxz) || !almostZero(myz) || !almostZero(mzx) - || !almostZero(mzy) || !almostOne(mzz) || !almostZero(mzt)) { - state |= APPLY_3D; - if (type != TYPE_UNKNOWN) { - type |= TYPE_AFFINE_3D; - } - } - } - - private double minor(int row, int col) { - double m00 = mxx, m01 = mxy, m02 = mxz; - double m10 = myx, m11 = myy, m12 = myz; - double m20 = mzx, m21 = mzy, m22 = mzz; - switch (col) { - case 0: - m00 = m01; - m10 = m11; - m20 = m21; - case 1: - m01 = m02; - m11 = m12; - m21 = m22; - case 2: - m02 = mxt; - m12 = myt; - m22 = mzt; - } - switch (row) { - case 0: - m00 = m10; - m01 = m11; - // m02 = m12; - case 1: - m10 = m20; - m11 = m21; - // m12 = m22; - case 2: - // m20 = 0.0; - // m21 = 0.0; - // m22 = 1.0; - break; - case 3: - // This is the only row that requires a full 3x3 determinant - return (m00 * (m11 * m22 - m21 * m12) - + m01 * (m12 * m20 - m22 * m10) - + m02 * (m10 * m21 - m20 * m11)); - } - // return (m00 * (m11 * 1.0 - 0.0 * m12) + - // m01 * (m12 * 0.0 - 1.0 * m10) + - // m02 * (m10 * 0.0 - 0.0 * m11)); - return (m00 * m11 - m01 * m10); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/AffineBase.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/AffineBase.java deleted file mode 100644 index bc4692f..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/AffineBase.java +++ /dev/null @@ -1,3173 +0,0 @@ -/* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Point2D; -import com.javafx.experiments.utils3d.geom.RectBounds; -import com.javafx.experiments.utils3d.geom.Rectangle; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public abstract class AffineBase extends BaseTransform { - - /** - * This constant is used for the internal state variable to indicate that - * the 3D (Z) components of the matrix (m*z and mz*) need to be factored in - * to complete the transformation equation of this transform. - * - * @see #APPLY_IDENTITY - * @see #APPLY_TRANSLATE - * @see #APPLY_SCALE - * @see #APPLY_SHEAR - * @see #state - */ - protected static final int APPLY_3D = 8; - - /** - * This constant is used for the internal state variable to indicate that no - * calculations need to be performed and that the source coordinates only - * need to be copied to their destinations to complete the transformation - * equation of this transform. - * - * @see #APPLY_TRANSLATE - * @see #APPLY_SCALE - * @see #APPLY_SHEAR - * @see #APPLY_3D - * @see #state - */ - protected static final int APPLY_IDENTITY = 0; - - /** - * This constant is used for the internal state variable to indicate that - * the scaling components of the matrix (m00 and m11) need to be factored in - * to complete the transformation equation of this transform. If the - * APPLY_SHEAR bit is also set then it indicates that the scaling components - * are not both 0.0. If the APPLY_SHEAR bit is not also set then it - * indicates that the scaling components are not both 1.0. If neither the - * APPLY_SHEAR nor the APPLY_SCALE bits are set then the scaling components - * are both 1.0, which means that the x and y components contribute to the - * transformed coordinate, but they are not multiplied by any scaling - * factor. - * - * @see #APPLY_IDENTITY - * @see #APPLY_TRANSLATE - * @see #APPLY_SHEAR - * @see #APPLY_3D - * @see #state - */ - protected static final int APPLY_SCALE = 2; - - /** - * This constant is used for the internal state variable to indicate that - * the shearing components of the matrix (m01 and m10) need to be factored - * in to complete the transformation equation of this transform. The - * presence of this bit in the state variable changes the interpretation of - * the APPLY_SCALE bit as indicated in its documentation. - * - * @see #APPLY_IDENTITY - * @see #APPLY_TRANSLATE - * @see #APPLY_SCALE - * @see #APPLY_3D - * @see #state - */ - protected static final int APPLY_SHEAR = 4; - /** - * This constant is used for the internal state variable to indicate that - * the translation components of the matrix (m02 and m12) need to be added - * to complete the transformation equation of this transform. - * - * @see #APPLY_IDENTITY - * @see #APPLY_SCALE - * @see #APPLY_SHEAR - * @see #APPLY_3D - * @see #state - */ - protected static final int APPLY_TRANSLATE = 1; - - protected static final int APPLY_2D_DELTA_MASK = (APPLY_SCALE - | APPLY_SHEAR); - - /* - * The following mask can be used to extract the 2D state constants from - * a state variable for cases where we know we can ignore the 3D matrix - * elements (such as in the 2D coordinate transform methods). - */ - protected static final int APPLY_2D_MASK = (APPLY_TRANSLATE - | APPLY_SCALE - | APPLY_SHEAR); - /* - * For methods which combine together the state of two separate - * transforms and dispatch based upon the combination, these constants - * specify how far to shift one of the states so that the two states - * are mutually non-interfering and provide constants for testing the - * bits of the shifted (HI) state. The methods in this class use - * the convention that the state of "this" transform is unshifted and - * the state of the "other" or "argument" transform is shifted (HI). - */ - protected static final int HI_SHIFT = 4; - protected static final int HI_TRANSLATE = APPLY_TRANSLATE << HI_SHIFT; - - protected static final int HI_3D = APPLY_3D << HI_SHIFT; - protected static final int HI_IDENTITY = APPLY_IDENTITY << HI_SHIFT; - protected static final int HI_SCALE = APPLY_SCALE << HI_SHIFT; - protected static final int HI_SHEAR = APPLY_SHEAR << HI_SHIFT; - - // Utility methods to optimize rotate methods. - // These tables translate the flags during predictable quadrant - // rotations where the shear and scale values are swapped and negated. - private static final int rot90conversion[] = { /* IDENTITY => */ APPLY_SHEAR, - /* TRANSLATE (TR) => */ APPLY_SHEAR - | APPLY_TRANSLATE, - /* SCALE (SC) => */ APPLY_SHEAR, - /* SC | TR => */ APPLY_SHEAR | APPLY_TRANSLATE, - /* SHEAR (SH) => */ APPLY_SCALE, - /* SH | TR => */ APPLY_SCALE | APPLY_TRANSLATE, - /* SH | SC => */ APPLY_SHEAR | APPLY_SCALE, - /* SH | SC | TR => */ APPLY_SHEAR | APPLY_SCALE - | APPLY_TRANSLATE, }; - - /* - * Convenience method used internally to throw exceptions when - * a case was forgotten in a switch statement. - */ - protected static void stateError() { - throw new InternalError("missing case in transform state switch"); - } - - /** - * The X coordinate of the translation element of the 3x3 affine - * transformation matrix. - */ - protected double mxt; - - /** - * The X coordinate scaling element of the 3x3 affine transformation matrix. - */ - protected double mxx; - - /** - * The X coordinate shearing element of the 3x3 affine transformation - * matrix. - */ - protected double mxy; - - /** - * The Y coordinate of the translation element of the 3x3 affine - * transformation matrix. - */ - protected double myt; - - /** - * The Y coordinate shearing element of the 3x3 affine transformation - * matrix. - */ - protected double myx; - - /** - * The Y coordinate scaling element of the 3x3 affine transformation matrix. - */ - protected double myy; - - /** - * This field keeps track of which components of the matrix need to be - * applied when performing a transformation. - * - * @see #APPLY_IDENTITY - * @see #APPLY_TRANSLATE - * @see #APPLY_SCALE - * @see #APPLY_SHEAR - * @see #APPLY_3D - */ - protected transient int state; - - /** - * This field caches the current transformation type of the matrix. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #TYPE_UNKNOWN - * @see #getType - */ - protected transient int type; - - /** - * Concatenates a BaseTransform Tx to this - * Affine2D Cx in the most commonly useful way to provide a new - * user space that is mapped to the former user space by Tx. Cx - * is updated to perform the combined transformation. Transforming a point p - * by the updated transform Cx' is equivalent to first transforming p by - * Tx and then transforming the result by the original - * transform Cx like this: Cx'(p) = Cx(Tx(p)) In matrix notation, if this - * transform Cx is represented by the matrix [this] and Tx is - * represented by the matrix [Tx] then this method does the following: - * - *

-     *      [this] = [this] x [Tx]
-     * 
- * - * @param Tx - * the BaseTransform object to be concatenated with - * this Affine2D object. - * @see #preConcatenate - */ - public void concatenate(BaseTransform Tx) { - switch (Tx.getDegree()) { - case IDENTITY: - return; - case TRANSLATE_2D: - translate(Tx.getMxt(), Tx.getMyt()); - return; - case AFFINE_2D: - break; - default: - if (!Tx.is2D()) { - degreeError(Degree.AFFINE_2D); - } - // TODO: Optimize - we need an AffineBase below due to the cast - // For now, there is no other kind of transform that will get - // here so we are already essentially optimal, but if we have - // a different type of transform that reaches here we should - // try to avoid this garbage... (RT-26884) - if (!(Tx instanceof AffineBase)) { - Tx = new Affine2D(Tx); - } - break; - } - double M0, M1; - double Txx, Txy, Tyx, Tyy; - double Txt, Tyt; - int mystate = state; - AffineBase at = (AffineBase) Tx; - int txstate = at.state; - switch ((txstate << HI_SHIFT) | mystate) { - - /* ---------- Tx == IDENTITY cases ---------- */ - case (HI_IDENTITY | APPLY_IDENTITY): - case (HI_IDENTITY | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SCALE): - case (HI_IDENTITY | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SHEAR): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE): - case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - return; - - /* ---------- this == IDENTITY cases ---------- */ - case (HI_SHEAR | HI_SCALE | HI_TRANSLATE | APPLY_IDENTITY): - mxy = at.mxy; - myx = at.myx; - /* NOBREAK */ - case (HI_SCALE | HI_TRANSLATE | APPLY_IDENTITY): - mxx = at.mxx; - myy = at.myy; - /* NOBREAK */ - case (HI_TRANSLATE | APPLY_IDENTITY): - mxt = at.mxt; - myt = at.myt; - state = txstate; - type = at.type; - return; - case (HI_SHEAR | HI_SCALE | APPLY_IDENTITY): - mxy = at.mxy; - myx = at.myx; - /* NOBREAK */ - case (HI_SCALE | APPLY_IDENTITY): - mxx = at.mxx; - myy = at.myy; - state = txstate; - type = at.type; - return; - case (HI_SHEAR | HI_TRANSLATE | APPLY_IDENTITY): - mxt = at.mxt; - myt = at.myt; - /* NOBREAK */ - case (HI_SHEAR | APPLY_IDENTITY): - mxy = at.mxy; - myx = at.myx; - mxx = myy = 0.0; - state = txstate; - type = at.type; - return; - - /* ---------- Tx == TRANSLATE cases ---------- */ - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE): - case (HI_TRANSLATE | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SHEAR): - case (HI_TRANSLATE | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_TRANSLATE | APPLY_SCALE): - case (HI_TRANSLATE | APPLY_TRANSLATE): - translate(at.mxt, at.myt); - return; - - /* ---------- Tx == SCALE cases ---------- */ - case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE): - case (HI_SCALE | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SHEAR): - case (HI_SCALE | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SCALE | APPLY_SCALE): - case (HI_SCALE | APPLY_TRANSLATE): - scale(at.mxx, at.myy); - return; - - /* ---------- Tx == SHEAR cases ---------- */ - case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE): - Txy = at.mxy; - Tyx = at.myx; - M0 = mxx; - mxx = mxy * Tyx; - mxy = M0 * Txy; - M0 = myx; - myx = myy * Tyx; - myy = M0 * Txy; - type = TYPE_UNKNOWN; - return; - case (HI_SHEAR | APPLY_SHEAR | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SHEAR): - mxx = mxy * at.myx; - mxy = 0.0; - myy = myx * at.mxy; - myx = 0.0; - state = mystate ^ (APPLY_SHEAR | APPLY_SCALE); - type = TYPE_UNKNOWN; - return; - case (HI_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (HI_SHEAR | APPLY_SCALE): - mxy = mxx * at.mxy; - mxx = 0.0; - myx = myy * at.myx; - myy = 0.0; - state = mystate ^ (APPLY_SHEAR | APPLY_SCALE); - type = TYPE_UNKNOWN; - return; - case (HI_SHEAR | APPLY_TRANSLATE): - mxx = 0.0; - mxy = at.mxy; - myx = at.myx; - myy = 0.0; - state = APPLY_TRANSLATE | APPLY_SHEAR; - type = TYPE_UNKNOWN; - return; - } - // If Tx has more than one attribute, it is not worth optimizing - // all of those cases... - Txx = at.mxx; - Txy = at.mxy; - Txt = at.mxt; - Tyx = at.myx; - Tyy = at.myy; - Tyt = at.myt; - switch (mystate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE): - state = mystate | txstate; - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - M0 = mxx; - M1 = mxy; - mxx = Txx * M0 + Tyx * M1; - mxy = Txy * M0 + Tyy * M1; - mxt += Txt * M0 + Tyt * M1; - - M0 = myx; - M1 = myy; - myx = Txx * M0 + Tyx * M1; - myy = Txy * M0 + Tyy * M1; - myt += Txt * M0 + Tyt * M1; - type = TYPE_UNKNOWN; - return; - - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - M0 = mxy; - mxx = Tyx * M0; - mxy = Tyy * M0; - mxt += Tyt * M0; - - M0 = myx; - myx = Txx * M0; - myy = Txy * M0; - myt += Txt * M0; - break; - - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - M0 = mxx; - mxx = Txx * M0; - mxy = Txy * M0; - mxt += Txt * M0; - - M0 = myy; - myx = Tyx * M0; - myy = Tyy * M0; - myt += Tyt * M0; - break; - - case (APPLY_TRANSLATE): - mxx = Txx; - mxy = Txy; - mxt += Txt; - - myx = Tyx; - myy = Tyy; - myt += Tyt; - state = txstate | APPLY_TRANSLATE; - type = TYPE_UNKNOWN; - return; - } - updateState2D(); - } - - /** - * Similar to - * {@link #concatenate(com.javafx.experiments.utils3d.geom.transform.BaseTransform)}, - * passing the individual elements of the transformation. - */ - public void concatenate(double Txx, double Txy, double Txt, double Tyx, - double Tyy, double Tyt) { - double rxx = (mxx * Txx + mxy * Tyx /* + mxt * 0.0 */); - double rxy = (mxx * Txy + mxy * Tyy /* + mxt * 0.0 */); - double rxt = (mxx * Txt + mxy * Tyt + mxt /* * 1.0 */); - double ryx = (myx * Txx + myy * Tyx /* + myt * 0.0 */); - double ryy = (myx * Txy + myy * Tyy /* + myt * 0.0 */); - double ryt = (myx * Txt + myy * Tyt + myt /* * 1.0 */); - this.mxx = rxx; - this.mxy = rxy; - this.mxt = rxt; - this.myx = ryx; - this.myy = ryy; - this.myt = ryt; - updateState(); - } - - /** - * Transforms an array of relative distance vectors by this transform. A - * relative distance vector is transformed without applying the translation - * components of the affine transformation matrix using the following - * equations: - * - *
-     *  [  x' ]   [  m00  m01 (m02) ] [  x  ]   [ m00x + m01y ]
-     *  [  y' ] = [  m10  m11 (m12) ] [  y  ] = [ m10x + m11y ]
-     *  [ (1) ]   [  (0)  (0) ( 1 ) ] [ (1) ]   [     (1)     ]
-     * 
- * - * The two coordinate array sections can be exactly the same or can be - * overlapping sections of the same array without affecting the validity of - * the results. This method ensures that no source coordinates are - * overwritten by a previous operation before they can be transformed. The - * coordinates are stored in the arrays starting at the indicated offset in - * the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source distance vectors. Each vector - * is stored as a pair of relative x, y coordinates. - * @param dstPts - * the array into which the transformed distance vectors are - * returned. Each vector is stored as a pair of relative - * x, y coordinates. - * @param srcOff - * the offset to the first vector to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed vector - * that is stored in the destination array - * @param numPts - * the number of vector coordinate pairs to be transformed - */ - @Override - public void deltaTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - doTransform(srcPts, srcOff, dstPts, dstOff, numPts, - (this.state & APPLY_2D_DELTA_MASK)); - } - - /** - * Transforms an array of relative distance vectors by this transform. A - * relative distance vector is transformed without applying the translation - * components of the affine transformation matrix using the following - * equations: - * - *
-     *  [  x' ]   [  m00  m01 (m02) ] [  x  ]   [ m00x + m01y ]
-     *  [  y' ] = [  m10  m11 (m12) ] [  y  ] = [ m10x + m11y ]
-     *  [ (1) ]   [  (0)  (0) ( 1 ) ] [ (1) ]   [     (1)     ]
-     * 
- * - * The two coordinate array sections can be exactly the same or can be - * overlapping sections of the same array without affecting the validity of - * the results. This method ensures that no source coordinates are - * overwritten by a previous operation before they can be transformed. The - * coordinates are stored in the arrays starting at the indicated offset in - * the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source distance vectors. Each vector - * is stored as a pair of relative x, y coordinates. - * @param dstPts - * the array into which the transformed distance vectors are - * returned. Each vector is stored as a pair of relative - * x, y coordinates. - * @param srcOff - * the offset to the first vector to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed vector - * that is stored in the destination array - * @param numPts - * the number of vector coordinate pairs to be transformed - */ - @Override - public void deltaTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - doTransform(srcPts, srcOff, dstPts, dstOff, numPts, - (this.state & APPLY_2D_DELTA_MASK)); - } - - /** - * Transforms the specified src vector and stores the result in - * dst vector, without applying the translation elements. If - * dst is null, a new - * {@link com.javafx.experiments.utils3d.geom.Vec3d} object is allocated and - * then the result of the transformation is stored in this object. In either - * case, dst, which contains the transformed vector, is - * returned for convenience. If src and dst are - * the same object, the input vector is correctly overwritten with the - * transformed vector. - * - * @param src - * the specified Vec3d to be transformed - * @param dst - * the specified Vec3d that stores the result of - * transforming src - * @return the dst vector after transforming src - * and storing the result in dst. - * @since JavaFX 8.0 - */ - @Override - public Vec3d deltaTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - // Copy source coords into local variables in case src == dst - double x = src.x; - double y = src.y; - double z = src.z; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - dst.x = x * mxx + y * mxy; - dst.y = x * myx + y * myy; - dst.z = z; - return dst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - dst.x = y * mxy; - dst.y = x * myx; - dst.z = z; - return dst; - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - dst.x = x * mxx; - dst.y = y * myy; - dst.z = z; - return dst; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - dst.x = x; - dst.y = y; - dst.z = z; - return dst; - } - - /* NOTREACHED */ - } - - /** - * Returns the determinant of the matrix representation of the transform. - * The determinant is useful both to determine if the transform can be - * inverted and to get a single value representing the combined X and Y - * scaling of the transform. - *

- * If the determinant is non-zero, then this transform is invertible and the - * various methods that depend on the inverse transform do not need to throw - * a {@link NoninvertibleTransformException}. If the determinant is zero - * then this transform can not be inverted since the transform maps all - * input coordinates onto a line or a point. If the determinant is near - * enough to zero then inverse transform operations might not carry enough - * precision to produce meaningful results. - *

- * If this transform represents a uniform scale, as indicated by the - * getType method then the determinant also represents the - * square of the uniform scale factor by which all of the points are - * expanded from or contracted towards the origin. If this transform - * represents a non-uniform scale or more general transform then the - * determinant is not likely to represent a value useful for any purpose - * other than determining if inverse transforms are possible. - *

- * Mathematically, the determinant is calculated using the formula: - * - *

-     *      |  mxx  mxy  mxt  |
-     *      |  myx  myy  myt  |  =  mxx * myy - mxy * myx
-     *      |   0    0    1   |
-     * 
- * - * @return the determinant of the matrix used to transform the coordinates. - * @see #getType - * @see #createInverse - * @see #inverseTransform - * @see #TYPE_UNIFORM_SCALE - */ - @Override - public double getDeterminant() { - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - return mxx * myy - mxy * myx; - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - return -(mxy * myx); - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - return mxx * myy; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - return 1.0; - } - } - - /** - * Returns the X coordinate of the translation element (mxt) of the 3x3 - * affine transformation matrix. - * - * @return a double value that is the X coordinate of the translation - * element of the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMxt() { - return mxt; - } - - /** - * Returns the X coordinate scaling element (mxx) of the 3x3 affine - * transformation matrix. - * - * @return a double value that is the X coordinate of the scaling element of - * the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMxx() { - return mxx; - } - - /** - * Returns the X coordinate shearing element (mxy) of the 3x3 affine - * transformation matrix. - * - * @return a double value that is the X coordinate of the shearing element - * of the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMxy() { - return mxy; - } - - /** - * Returns the Y coordinate of the translation element (myt) of the 3x3 - * affine transformation matrix. - * - * @return a double value that is the Y coordinate of the translation - * element of the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMyt() { - return myt; - } - - /** - * Returns the Y coordinate shearing element (myx) of the 3x3 affine - * transformation matrix. - * - * @return a double value that is the Y coordinate of the shearing element - * of the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMyx() { - return myx; - } - - /** - * Returns the Y coordinate scaling element (myy) of the 3x3 affine - * transformation matrix. - * - * @return a double value that is the Y coordinate of the scaling element of - * the affine transformation matrix. - * @see #getMatrix - */ - @Override - public double getMyy() { - return myy; - } - - @Override - public int getType() { - if (type == TYPE_UNKNOWN) { - updateState(); // TODO: Is this really needed? (RT-26884) - if (type == TYPE_UNKNOWN) { - type = calculateType(); - } - } - return type; - } - - /** - * Inverse transforms an array of single precision relative coordinates by - * this transform. The two coordinate array sections can be exactly the same - * or can be overlapping sections of the same array without affecting the - * validity of the results. This method ensures that no source coordinates - * are overwritten by a previous operation before they can be transformed. - * The coordinates are stored in the arrays starting at the specified offset - * in the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the relative source coordinates. Each - * point is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the relative transformed point - * coordinates are returned. Each point is stored as a pair of - * x, y coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of point objects to be transformed - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - */ - @Override - public void inverseDeltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int numPts) throws NoninvertibleTransformException { - doInverseTransform(srcPts, srcOff, dstPts, dstOff, numPts, - state & ~APPLY_TRANSLATE); - } - - /** - * Inverse transforms the specified src vector and stores the - * result in dst vector (without applying the translation - * elements). If dst is null, a new - * Vec3d object is allocated and then the result of the - * transform is stored in this object. In either case, dst, - * which contains the transformed vector, is returned for convenience. If - * src and dst are the same object, the input - * vector is correctly overwritten with the transformed vector. - * - * @param src - * the vector to be inverse transformed - * @param dst - * the resulting transformed vector - * @return dst, which contains the result of the inverse - * transform. - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - * @since JavaFX 8.0 - */ - @Override - public Vec3d inverseDeltaTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException { - if (dst == null) { - dst = new Vec3d(); - } - // Copy source coords into local variables in case src == dst - double x = src.x; - double y = src.y; - double z = src.z; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - double det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - dst.set(((x * myy - y * mxy) / det), - ((y * mxx - x * myx) / det), z); - return dst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.set((y / myx), (x / mxy), z); - return dst; - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.set((x / mxx), (y / myy), z); - return dst; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - dst.set(x, y, z); - return dst; - } - - /* NOTREACHED */ - } - - @Override - public BaseBounds inverseTransform(BaseBounds src, - BaseBounds dst) throws NoninvertibleTransformException { - // assert(APPLY_3D was dealt with at a higher level) - if (!src.is2D() || !dst.is2D()) { - return inversTransform3DBounds(src, dst); - } - return inversTransform2DBounds((RectBounds) src, (RectBounds) dst); - } - - /** - * Inverse transforms an array of double precision coordinates by this - * transform. The two coordinate array sections can be exactly the same or - * can be overlapping sections of the same array without affecting the - * validity of the results. This method ensures that no source coordinates - * are overwritten by a previous operation before they can be transformed. - * The coordinates are stored in the arrays starting at the specified offset - * in the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of point objects to be transformed - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - */ - @Override - public void inverseTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, - int numPts) throws NoninvertibleTransformException { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - double det; - if (dstPts == srcPts && dstOff > srcOff - && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++] - Mxt; - double y = srcPts[srcOff++] - Myt; - dstPts[dstOff++] = (x * Myy - y * Mxy) / det; - dstPts[dstOff++] = (y * Mxx - x * Myx) / det; - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (x * Myy - y * Mxy) / det; - dstPts[dstOff++] = (y * Mxx - x * Myx) / det; - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++] - Mxt; - dstPts[dstOff++] = (srcPts[srcOff++] - Myt) / Myx; - dstPts[dstOff++] = x / Mxy; - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = srcPts[srcOff++] / Myx; - dstPts[dstOff++] = x / Mxy; - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - dstPts[dstOff++] = (srcPts[srcOff++] - Mxt) / Mxx; - dstPts[dstOff++] = (srcPts[srcOff++] - Myt) / Myy; - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - dstPts[dstOff++] = srcPts[srcOff++] / Mxx; - dstPts[dstOff++] = srcPts[srcOff++] / Myy; - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = srcPts[srcOff++] - Mxt; - dstPts[dstOff++] = srcPts[srcOff++] - Myt; - } - return; - case (APPLY_IDENTITY): - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, - numPts * 2); - } - return; - } - /* NOTREACHED */ - } - - /** - * Inverse transforms an array of single precision coordinates by this - * transform. The two coordinate array sections can be exactly the same or - * can be overlapping sections of the same array without affecting the - * validity of the results. This method ensures that no source coordinates - * are overwritten by a previous operation before they can be transformed. - * The coordinates are stored in the arrays starting at the specified offset - * in the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of point objects to be transformed - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - */ - @Override - public void inverseTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, - int numPts) throws NoninvertibleTransformException { - doInverseTransform(srcPts, srcOff, dstPts, dstOff, numPts, state); - } - - /** - * Inverse transforms the specified ptSrc and stores the result - * in ptDst. If ptDst is null, a new - * Point2D object is allocated and then the result of the - * transform is stored in this object. In either case, ptDst, - * which contains the transformed point, is returned for convenience. If - * ptSrc and ptDst are the same object, the input - * point is correctly overwritten with the transformed point. - * - * @param ptSrc - * the point to be inverse transformed - * @param ptDst - * the resulting transformed point - * @return ptDst, which contains the result of the inverse - * transform. - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - */ - @Override - public Point2D inverseTransform(Point2D ptSrc, - Point2D ptDst) throws NoninvertibleTransformException { - if (ptDst == null) { - ptDst = new Point2D(); - } - // Copy source coords into local variables in case src == dst - double x = ptSrc.x; - double y = ptSrc.y; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - double det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - ptDst.setLocation((float) ((x * myy - y * mxy) / det), - (float) ((y * mxx - x * myx) / det)); - return ptDst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SHEAR): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - ptDst.setLocation((float) (y / myx), (float) (x / mxy)); - return ptDst; - case (APPLY_SCALE | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - ptDst.setLocation((float) (x / mxx), (float) (y / myy)); - return ptDst; - case (APPLY_TRANSLATE): - ptDst.setLocation((float) (x - mxt), (float) (y - myt)); - return ptDst; - case (APPLY_IDENTITY): - ptDst.setLocation((float) x, (float) y); - return ptDst; - } - - /* NOTREACHED */ - } - - @Override - public void inverseTransform(Rectangle src, - Rectangle dst) throws NoninvertibleTransformException { - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - RectBounds b = new RectBounds(src); - //TODO: Need to verify this casting is safe .... (RT-26885) - b = (RectBounds) inverseTransform(b, b); - dst.setBounds(b); - return; - case (APPLY_TRANSLATE): - Translate2D.transform(src, dst, -mxt, -myt); - return; - case (APPLY_IDENTITY): - if (dst != src) { - dst.setBounds(src); - } - return; - } - } - - /** - * Inverse transforms the specified src and stores the result - * in dst. If dst is null, a new - * Vec3d object is allocated and then the result of the - * transform is stored in this object. In either case, dst, - * which contains the transformed point, is returned for convenience. If - * src and dst are the same object, the input - * point is correctly overwritten with the transformed point. - * - * @param src - * the point to be inverse transformed - * @param dst - * the resulting transformed point - * @return dst, which contains the result of the inverse - * transform. - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - */ - @Override - public Vec3d inverseTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException { - if (dst == null) { - dst = new Vec3d(); - } - // Copy source coords into local variables in case src == dst - double x = src.x; - double y = src.y; - double z = src.z; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - double det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - dst.set(((x * myy - y * mxy) / det), - ((y * mxx - x * myx) / det), z); - return dst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SHEAR): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.set((y / myx), (x / mxy), z); - return dst; - case (APPLY_SCALE | APPLY_TRANSLATE): - x -= mxt; - y -= myt; - /* NOBREAK */ - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.set((x / mxx), (y / myy), z); - return dst; - case (APPLY_TRANSLATE): - dst.set((x - mxt), (y - myt), z); - return dst; - case (APPLY_IDENTITY): - dst.set(x, y, z); - return dst; - } - - /* NOTREACHED */ - } - - /** - * Sets this transform to the inverse of itself. The inverse transform Tx' - * of this transform Tx maps coordinates transformed by Tx back to their - * original coordinates. In other words, Tx'(Tx(p)) = p = Tx(Tx'(p)). - *

- * If this transform maps all coordinates onto a point or a line then it - * will not have an inverse, since coordinates that do not lie on the - * destination point or line will not have an inverse mapping. The - * getDeterminant method can be used to determine if this - * transform has no inverse, in which case an exception will be thrown if - * the invert method is called. - * - * @throws NoninvertibleTransformException - * if the matrix cannot be inverted. - * @see #getDeterminant - */ - @Override - public void invert() throws NoninvertibleTransformException { - double Mxx, Mxy, Mxt; - double Myx, Myy, Myt; - double det; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - mxx = Myy / det; - myx = -Myx / det; - mxy = -Mxy / det; - myy = Mxx / det; - mxt = (Mxy * Myt - Myy * Mxt) / det; - myt = (Myx * Mxt - Mxx * Myt) / det; - break; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - mxx = Myy / det; - myx = -Myx / det; - mxy = -Mxy / det; - myy = Mxx / det; - // m02 = 0.0; - // m12 = 0.0; - break; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - // m00 = 0.0; - myx = 1.0 / Mxy; - mxy = 1.0 / Myx; - // m11 = 0.0; - mxt = -Myt / Myx; - myt = -Mxt / Mxy; - break; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - // m00 = 0.0; - myx = 1.0 / Mxy; - mxy = 1.0 / Myx; - // m11 = 0.0; - // m02 = 0.0; - // m12 = 0.0; - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - mxx = 1.0 / Mxx; - // m10 = 0.0; - // m01 = 0.0; - myy = 1.0 / Myy; - mxt = -Mxt / Mxx; - myt = -Myt / Myy; - break; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - mxx = 1.0 / Mxx; - // m10 = 0.0; - // m01 = 0.0; - myy = 1.0 / Myy; - // m02 = 0.0; - // m12 = 0.0; - break; - case (APPLY_TRANSLATE): - // m00 = 1.0; - // m10 = 0.0; - // m01 = 0.0; - // m11 = 1.0; - mxt = -mxt; - myt = -myt; - break; - case (APPLY_IDENTITY): - // m00 = 1.0; - // m10 = 0.0; - // m01 = 0.0; - // m11 = 1.0; - // m02 = 0.0; - // m12 = 0.0; - break; - } - } - - @Override - public boolean is2D() { - return (state < APPLY_3D || getType() <= TYPE_AFFINE2D_MASK); - } - - /** - * Returns true if this Affine2D is an identity - * transform. - * - * @return true if this Affine2D is an identity - * transform; false otherwise. - */ - @Override - public boolean isIdentity() { - return (state == APPLY_IDENTITY || (getType() == TYPE_IDENTITY)); - } - - @Override - public boolean isTranslateOrIdentity() { - return (state <= APPLY_TRANSLATE || (getType() <= TYPE_TRANSLATION)); - } - - /** - * Concatenates this transform with a rotation transformation. This is - * equivalent to calling concatenate(R), where R is an Affine2D - * represented by the following matrix: - * - *

-     *      [   cos(theta)    -sin(theta)    0   ]
-     *      [   sin(theta)     cos(theta)    0   ]
-     *      [       0              0         1   ]
-     * 
- * - * Rotating by a positive angle theta rotates points on the positive X axis - * toward the positive Y axis. Note also the discussion of - * Handling 90-Degree Rotations above. - * - * @param theta - * the angle of rotation measured in radians - */ - public void rotate(double theta) { - // assert(APPLY_3D was dealt with at a higher level) - double sin = Math.sin(theta); - if (sin == 1.0) { - rotate90(); - } else if (sin == -1.0) { - rotate270(); - } else { - double cos = Math.cos(theta); - if (cos == -1.0) { - rotate180(); - } else if (cos != 1.0) { - double M0, M1; - M0 = mxx; - M1 = mxy; - mxx = cos * M0 + sin * M1; - mxy = -sin * M0 + cos * M1; - M0 = myx; - M1 = myy; - myx = cos * M0 + sin * M1; - myy = -sin * M0 + cos * M1; - updateState2D(); - } - } - } - - /** - * Concatenates this transform with a scaling transformation. This is - * equivalent to calling concatenate(S), where S is an Affine2D - * represented by the following matrix: - * - *
-     *      [   sx   0    0   ]
-     *      [   0    sy   0   ]
-     *      [   0    0    1   ]
-     * 
- * - * @param sx - * the factor by which coordinates are scaled along the X axis - * direction - * @param sy - * the factor by which coordinates are scaled along the Y axis - * direction - */ - public void scale(double sx, double sy) { - int mystate = this.state; - // assert(APPLY_3D was dealt with at a higher level) - switch (mystate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - mxx *= sx; - myy *= sy; - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - mxy *= sy; - myx *= sx; - if (mxy == 0 && myx == 0) { - mystate &= APPLY_TRANSLATE; - if (mxx == 1.0 && myy == 1.0) { - this.type = (mystate == APPLY_IDENTITY ? TYPE_IDENTITY - : TYPE_TRANSLATION); - } else { - mystate |= APPLY_SCALE; - this.type = TYPE_UNKNOWN; - } - this.state = mystate; - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - mxx *= sx; - myy *= sy; - if (mxx == 1.0 && myy == 1.0) { - this.state = (mystate &= APPLY_TRANSLATE); - this.type = (mystate == APPLY_IDENTITY ? TYPE_IDENTITY - : TYPE_TRANSLATION); - } else { - this.type = TYPE_UNKNOWN; - } - return; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - mxx = sx; - myy = sy; - if (sx != 1.0 || sy != 1.0) { - this.state = mystate | APPLY_SCALE; - this.type = TYPE_UNKNOWN; - } - return; - } - } - - /** - * Resets this transform to the Identity transform. - */ - @Override - public void setToIdentity() { - mxx = myy = 1.0; - myx = mxy = mxt = myt = 0.0; - reset3Delements(); - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - - /** - * Sets this transform to a shearing transformation. The matrix representing - * this transform becomes: - * - *
-     *      [   1   shx   0   ]
-     *      [  shy   1    0   ]
-     *      [   0    0    1   ]
-     * 
- * - * @param shx - * the multiplier by which coordinates are shifted in the - * direction of the positive X axis as a factor of their Y - * coordinate - * @param shy - * the multiplier by which coordinates are shifted in the - * direction of the positive Y axis as a factor of their X - * coordinate - */ - public void setToShear(double shx, double shy) { - mxx = 1.0; - mxy = shx; - myx = shy; - myy = 1.0; - mxt = 0.0; - myt = 0.0; - reset3Delements(); - if (shx != 0.0 || shy != 0.0) { - state = (APPLY_SHEAR | APPLY_SCALE); - type = TYPE_UNKNOWN; - } else { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - } - - /** - * Sets this transform to the matrix specified by the 6 double precision - * values. - * - * @param mxx - * the X coordinate scaling element of the 3x3 matrix - * @param myx - * the Y coordinate shearing element of the 3x3 matrix - * @param mxy - * the X coordinate shearing element of the 3x3 matrix - * @param myy - * the Y coordinate scaling element of the 3x3 matrix - * @param mxt - * the X coordinate translation element of the 3x3 matrix - * @param myt - * the Y coordinate translation element of the 3x3 matrix - */ - public void setTransform(double mxx, double myx, double mxy, double myy, - double mxt, double myt) { - this.mxx = mxx; - this.myx = myx; - this.mxy = mxy; - this.myy = myy; - this.mxt = mxt; - this.myt = myt; - reset3Delements(); - updateState2D(); - } - - /** - * Concatenates this transform with a shearing transformation. This is - * equivalent to calling concatenate(SH), where SH is an - * Affine2D represented by the following matrix: - * - *
-     *      [   1   shx   0   ]
-     *      [  shy   1    0   ]
-     *      [   0    0    1   ]
-     * 
- * - * @param shx - * the multiplier by which coordinates are shifted in the - * direction of the positive X axis as a factor of their Y - * coordinate - * @param shy - * the multiplier by which coordinates are shifted in the - * direction of the positive Y axis as a factor of their X - * coordinate - */ - public void shear(double shx, double shy) { - int mystate = this.state; - // assert(APPLY_3D was dealt with at a higher level) - switch (mystate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - double M0, M1; - M0 = mxx; - M1 = mxy; - mxx = M0 + M1 * shy; - mxy = M0 * shx + M1; - - M0 = myx; - M1 = myy; - myx = M0 + M1 * shy; - myy = M0 * shx + M1; - updateState2D(); - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - mxx = mxy * shy; - myy = myx * shx; - if (mxx != 0.0 || myy != 0.0) { - this.state = mystate | APPLY_SCALE; - } - this.type = TYPE_UNKNOWN; - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - mxy = mxx * shx; - myx = myy * shy; - if (mxy != 0.0 || myx != 0.0) { - this.state = mystate | APPLY_SHEAR; - } - this.type = TYPE_UNKNOWN; - return; - case (APPLY_TRANSLATE): - case (APPLY_IDENTITY): - mxy = shx; - myx = shy; - if (mxy != 0.0 || myx != 0.0) { - this.state = mystate | APPLY_SCALE | APPLY_SHEAR; - this.type = TYPE_UNKNOWN; - } - return; - } - } - - @Override - public BaseBounds transform(BaseBounds src, BaseBounds dst) { - // assert(APPLY_3D was dealt with at a higher level) - if (!src.is2D() || !dst.is2D()) { - return transform3DBounds(src, dst); - } - return transform2DBounds((RectBounds) src, (RectBounds) dst); - } - - /** - * Transforms an array of double precision coordinates by this transform. - * The two coordinate array sections can be exactly the same or can be - * overlapping sections of the same array without affecting the validity of - * the results. This method ensures that no source coordinates are - * overwritten by a previous operation before they can be transformed. The - * coordinates are stored in the arrays starting at the indicated offset in - * the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of point objects to be transformed - */ - @Override - public void transform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - doTransform(srcPts, srcOff, dstPts, dstOff, numPts, - (this.state & APPLY_2D_MASK)); - } - - /** - * Transforms an array of double precision coordinates by this transform and - * stores the results into an array of floats. The coordinates are stored in - * the arrays starting at the specified offset in the order - * [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of point objects to be transformed - */ - @Override - public void transform(double[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - // Note that this method also works for 3D transforms since the - // mxz and myz matrix elements get multiplied by z (0.0) and the - // mzx, mzy, mzz, and mzt elements only get used to calculate - // the resulting Z coordinate, which we drop (ignore). - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxx * x + Mxy * y + Mxt); - dstPts[dstOff++] = (float) (Myx * x + Myy * y + Myt); - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxx * x + Mxy * y); - dstPts[dstOff++] = (float) (Myx * x + Myy * y); - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxy * srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (Myx * x + Myt); - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxy * srcPts[srcOff++]); - dstPts[dstOff++] = (float) (Myx * x); - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (Mxx * srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (Myy * srcPts[srcOff++] + Myt); - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (Mxx * srcPts[srcOff++]); - dstPts[dstOff++] = (float) (Myy * srcPts[srcOff++]); - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (srcPts[srcOff++] + Myt); - } - return; - case (APPLY_IDENTITY): - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (srcPts[srcOff++]); - dstPts[dstOff++] = (float) (srcPts[srcOff++]); - } - return; - } - - /* NOTREACHED */ - } - - /** - * Transforms an array of floating point coordinates by this transform and - * stores the results into an array of doubles. The coordinates are stored - * in the arrays starting at the specified offset in the order - * [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of points to be transformed - */ - @Override - public void transform(float[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - // Note that this method also works for 3D transforms since the - // mxz and myz matrix elements get multiplied by z (0.0) and the - // mzx, mzy, mzz, and mzt elements only get used to calculate - // the resulting Z coordinate, which we drop (ignore). - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = Mxx * x + Mxy * y + Mxt; - dstPts[dstOff++] = Myx * x + Myy * y + Myt; - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = Mxx * x + Mxy * y; - dstPts[dstOff++] = Myx * x + Myy * y; - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = Mxy * srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = Myx * x + Myt; - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = Mxy * srcPts[srcOff++]; - dstPts[dstOff++] = Myx * x; - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = Mxx * srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = Myy * srcPts[srcOff++] + Myt; - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - while (--numPts >= 0) { - dstPts[dstOff++] = Mxx * srcPts[srcOff++]; - dstPts[dstOff++] = Myy * srcPts[srcOff++]; - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = srcPts[srcOff++] + Myt; - } - return; - case (APPLY_IDENTITY): - while (--numPts >= 0) { - dstPts[dstOff++] = srcPts[srcOff++]; - dstPts[dstOff++] = srcPts[srcOff++]; - } - return; - } - - /* NOTREACHED */ - } - - /** - * Transforms an array of floating point coordinates by this transform. The - * two coordinate array sections can be exactly the same or can be - * overlapping sections of the same array without affecting the validity of - * the results. This method ensures that no source coordinates are - * overwritten by a previous operation before they can be transformed. The - * coordinates are stored in the arrays starting at the specified offset in - * the order [x0, y0, x1, y1, ..., xn, yn]. - * - * @param srcPts - * the array containing the source point coordinates. Each point - * is stored as a pair of x, y coordinates. - * @param dstPts - * the array into which the transformed point coordinates are - * returned. Each point is stored as a pair of x, y - * coordinates. - * @param srcOff - * the offset to the first point to be transformed in the source - * array - * @param dstOff - * the offset to the location of the first transformed point that - * is stored in the destination array - * @param numPts - * the number of points to be transformed - */ - @Override - public void transform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - doTransform(srcPts, srcOff, dstPts, dstOff, numPts, - (this.state & APPLY_2D_MASK)); - } - - public Point2D transform(Point2D pt) { - return transform(pt, pt); - } - - /** - * Transforms the specified ptSrc and stores the result in - * ptDst. If ptDst is null, a new - * {@link com.javafx.experiments.utils3d.geom.Point2D} object is allocated - * and then the result of the transformation is stored in this object. In - * either case, ptDst, which contains the transformed point, is - * returned for convenience. If ptSrc and ptDst - * are the same object, the input point is correctly overwritten with the - * transformed point. - * - * @param ptSrc - * the specified Point2D to be transformed - * @param ptDst - * the specified Point2D that stores the result of - * transforming ptSrc - * @return the ptDst after transforming ptSrc and - * stroring the result in ptDst. - */ - @Override - public Point2D transform(Point2D ptSrc, Point2D ptDst) { - if (ptDst == null) { - ptDst = new Point2D(); - } - // Copy source coords into local variables in case src == dst - double x = ptSrc.x; - double y = ptSrc.y; - // double z = 0.0 - // Note that this method also works for 3D transforms since the - // mxz and myz matrix elements get multiplied by z (0.0) and the - // mzx, mzy, mzz, and mzt elements only get used to calculate - // the resulting Z coordinate, which we drop (ignore). - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - ptDst.setLocation((float) (x * mxx + y * mxy + mxt), - (float) (x * myx + y * myy + myt)); - return ptDst; - case (APPLY_SHEAR | APPLY_SCALE): - ptDst.setLocation((float) (x * mxx + y * mxy), - (float) (x * myx + y * myy)); - return ptDst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - ptDst.setLocation((float) (y * mxy + mxt), - (float) (x * myx + myt)); - return ptDst; - case (APPLY_SHEAR): - ptDst.setLocation((float) (y * mxy), (float) (x * myx)); - return ptDst; - case (APPLY_SCALE | APPLY_TRANSLATE): - ptDst.setLocation((float) (x * mxx + mxt), - (float) (y * myy + myt)); - return ptDst; - case (APPLY_SCALE): - ptDst.setLocation((float) (x * mxx), (float) (y * myy)); - return ptDst; - case (APPLY_TRANSLATE): - ptDst.setLocation((float) (x + mxt), (float) (y + myt)); - return ptDst; - case (APPLY_IDENTITY): - ptDst.setLocation((float) x, (float) y); - return ptDst; - } - - /* NOTREACHED */ - } - - @Override - public void transform(Rectangle src, Rectangle dst) { - // assert(APPLY_3D was dealt with at a higher level) - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SHEAR | APPLY_SCALE): - case (APPLY_SHEAR | APPLY_TRANSLATE): - case (APPLY_SHEAR): - case (APPLY_SCALE | APPLY_TRANSLATE): - case (APPLY_SCALE): - RectBounds b = new RectBounds(src); - //TODO: Need to verify that this is a safe cast ... (RT-26885) - b = (RectBounds) transform(b, b); - dst.setBounds(b); - return; - case (APPLY_TRANSLATE): - Translate2D.transform(src, dst, mxt, myt); - return; - case (APPLY_IDENTITY): - if (dst != src) { - dst.setBounds(src); - } - return; - } - } - - @Override - public Vec3d transform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - // Copy source coords into local variables in case src == dst - double x = src.x; - double y = src.y; - double z = src.z; - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - dst.x = x * mxx + y * mxy + mxt; - dst.y = x * myx + y * myy + myt; - dst.z = z; - return dst; - case (APPLY_SHEAR | APPLY_SCALE): - dst.x = x * mxx + y * mxy; - dst.y = x * myx + y * myy; - dst.z = z; - return dst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - dst.x = y * mxy + mxt; - dst.y = x * myx + myt; - dst.z = z; - return dst; - case (APPLY_SHEAR): - dst.x = y * mxy; - dst.y = x * myx; - dst.z = z; - return dst; - case (APPLY_SCALE | APPLY_TRANSLATE): - dst.x = x * mxx + mxt; - dst.y = y * myy + myt; - dst.z = z; - return dst; - case (APPLY_SCALE): - dst.x = x * mxx; - dst.y = y * myy; - dst.z = z; - return dst; - case (APPLY_TRANSLATE): - dst.x = x + mxt; - dst.y = y + myt; - dst.z = z; - return dst; - case (APPLY_IDENTITY): - dst.x = x; - dst.y = y; - dst.z = z; - return dst; - } - - /* NOTREACHED */ - } - - /** - * Concatenates this transform with a translation transformation. This is - * equivalent to calling concatenate(T), where T is an Affine2D - * represented by the following matrix: - * - *
-     *      [   1    0    tx  ]
-     *      [   0    1    ty  ]
-     *      [   0    0    1   ]
-     * 
- * - * @param tx - * the distance by which coordinates are translated in the X axis - * direction - * @param ty - * the distance by which coordinates are translated in the Y axis - * direction - */ - public void translate(double tx, double ty) { - // assert(APPLY_3D was dealt with at a higher level) - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - mxt = tx * mxx + ty * mxy + mxt; - myt = tx * myx + ty * myy + myt; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SHEAR | APPLY_SCALE; - if (type != TYPE_UNKNOWN) { - type &= ~TYPE_TRANSLATION; - } - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - mxt = tx * mxx + ty * mxy; - myt = tx * myx + ty * myy; - if (mxt != 0.0 || myt != 0.0) { - state = APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - mxt = ty * mxy + mxt; - myt = tx * myx + myt; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SHEAR; - if (type != TYPE_UNKNOWN) { - type &= ~TYPE_TRANSLATION; - } - } - return; - case (APPLY_SHEAR): - mxt = ty * mxy; - myt = tx * myx; - if (mxt != 0.0 || myt != 0.0) { - state = APPLY_SHEAR | APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - mxt = tx * mxx + mxt; - myt = ty * myy + myt; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SCALE; - if (type != TYPE_UNKNOWN) { - type &= ~TYPE_TRANSLATION; - } - } - return; - case (APPLY_SCALE): - mxt = tx * mxx; - myt = ty * myy; - if (mxt != 0.0 || myt != 0.0) { - state = APPLY_SCALE | APPLY_TRANSLATE; - type |= TYPE_TRANSLATION; - } - return; - case (APPLY_TRANSLATE): - mxt = tx + mxt; - myt = ty + myt; - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } - return; - case (APPLY_IDENTITY): - mxt = tx; - myt = ty; - if (tx != 0.0 || ty != 0.0) { - state = APPLY_TRANSLATE; - type = TYPE_TRANSLATION; - } - return; - } - } - - protected int calculateType() { - int ret = ((state & APPLY_3D) == 0) ? TYPE_IDENTITY : TYPE_AFFINE_3D; - boolean sgn0, sgn1; - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - ret |= TYPE_TRANSLATION; - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - if (mxx * mxy + myx * myy != 0) { - // Transformed unit vectors are not perpendicular... - ret |= TYPE_GENERAL_TRANSFORM; - break; - } - sgn0 = (mxx >= 0.0); - sgn1 = (myy >= 0.0); - if (sgn0 == sgn1) { - // sgn(mxx) == sgn(myy) therefore sgn(mxy) == -sgn(myx) - // This is the "unflipped" (right-handed) state - if (mxx != myy || mxy != -myx) { - ret |= (TYPE_GENERAL_ROTATION | TYPE_GENERAL_SCALE); - } else if (mxx * myy - mxy * myx != 1.0) { - ret |= (TYPE_GENERAL_ROTATION | TYPE_UNIFORM_SCALE); - } else { - ret |= TYPE_GENERAL_ROTATION; - } - } else { - // sgn(mxx) == -sgn(myy) therefore sgn(mxy) == sgn(myx) - // This is the "flipped" (left-handed) state - if (mxx != -myy || mxy != myx) { - ret |= (TYPE_GENERAL_ROTATION | TYPE_FLIP - | TYPE_GENERAL_SCALE); - } else if (mxx * myy - mxy * myx != 1.0) { - ret |= (TYPE_GENERAL_ROTATION | TYPE_FLIP - | TYPE_UNIFORM_SCALE); - } else { - ret |= (TYPE_GENERAL_ROTATION | TYPE_FLIP); - } - } - break; - case (APPLY_SHEAR | APPLY_TRANSLATE): - ret |= TYPE_TRANSLATION; - /* NOBREAK */ - case (APPLY_SHEAR): - sgn0 = (mxy >= 0.0); - sgn1 = (myx >= 0.0); - if (sgn0 != sgn1) { - // Different signs - simple 90 degree rotation - if (mxy != -myx) { - ret |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE); - } else if (mxy != 1.0 && mxy != -1.0) { - ret |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE); - } else { - ret |= TYPE_QUADRANT_ROTATION; - } - } else { - // Same signs - 90 degree rotation plus an axis flip too - if (mxy == myx) { - ret |= (TYPE_QUADRANT_ROTATION | TYPE_FLIP - | TYPE_UNIFORM_SCALE); - } else { - ret |= (TYPE_QUADRANT_ROTATION | TYPE_FLIP - | TYPE_GENERAL_SCALE); - } - } - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - ret |= TYPE_TRANSLATION; - /* NOBREAK */ - case (APPLY_SCALE): - sgn0 = (mxx >= 0.0); - sgn1 = (myy >= 0.0); - if (sgn0 == sgn1) { - if (sgn0) { - // Both scaling factors non-negative - simple scale - // Note: APPLY_SCALE implies M0, M1 are not both 1 - if (mxx == myy) { - ret |= TYPE_UNIFORM_SCALE; - } else { - ret |= TYPE_GENERAL_SCALE; - } - } else { - // Both scaling factors negative - 180 degree rotation - if (mxx != myy) { - ret |= (TYPE_QUADRANT_ROTATION - | TYPE_GENERAL_SCALE); - } else if (mxx != -1.0) { - ret |= (TYPE_QUADRANT_ROTATION - | TYPE_UNIFORM_SCALE); - } else { - ret |= TYPE_QUADRANT_ROTATION; - } - } - } else { - // Scaling factor signs different - flip about some axis - if (mxx == -myy) { - if (mxx == 1.0 || mxx == -1.0) { - ret |= TYPE_FLIP; - } else { - ret |= (TYPE_FLIP | TYPE_UNIFORM_SCALE); - } - } else { - ret |= (TYPE_FLIP | TYPE_GENERAL_SCALE); - } - } - break; - case (APPLY_TRANSLATE): - ret |= TYPE_TRANSLATION; - break; - case (APPLY_IDENTITY): - break; - } - return ret; - } - - /** - * Resets the 3D (Z) components of the matrix to identity settings (if they - * are present). This is a NOP unless the transform is Affine3D in which - * case it needs to reset its added fields. - */ - protected abstract void reset3Delements(); - - protected final void rotate180() { - mxx = -mxx; - myy = -myy; - int oldstate = this.state; - if ((oldstate & (APPLY_SHEAR)) != 0) { - // If there was a shear, then this rotation has no - // effect on the state. - mxy = -mxy; - myx = -myx; - } else { - // No shear means the SCALE state may toggle when - // m00 and m11 are negated. - if (mxx == 1.0 && myy == 1.0) { - this.state = oldstate & ~APPLY_SCALE; - } else { - this.state = oldstate | APPLY_SCALE; - } - } - type = TYPE_UNKNOWN; - } - - protected final void rotate270() { - double M0 = mxx; - mxx = -mxy; - mxy = M0; - M0 = myx; - myx = -myy; - myy = M0; - int newstate = rot90conversion[this.state]; - if ((newstate & (APPLY_SHEAR | APPLY_SCALE)) == APPLY_SCALE - && mxx == 1.0 && myy == 1.0) { - newstate -= APPLY_SCALE; - } - this.state = newstate; - type = TYPE_UNKNOWN; - } - - protected final void rotate90() { - double M0 = mxx; - mxx = mxy; - mxy = -M0; - M0 = myx; - myx = myy; - myy = -M0; - int newstate = rot90conversion[this.state]; - if ((newstate & (APPLY_SHEAR | APPLY_SCALE)) == APPLY_SCALE - && mxx == 1.0 && myy == 1.0) { - newstate -= APPLY_SCALE; - } - this.state = newstate; - type = TYPE_UNKNOWN; - } - - /** - * Manually recalculates the state of the transform when the matrix changes - * too much to predict the effects on the state. The following table - * specifies what the various settings of the state field say about the - * values of the corresponding matrix element fields. Note that the rules - * governing the SCALE fields are slightly different depending on whether - * the SHEAR flag is also set. - * - *
-     *                     SCALE            SHEAR          TRANSLATE
-     *                    m00/m11          m01/m10          m02/m12
-     *
-     * IDENTITY             1.0              0.0              0.0
-     * TRANSLATE (TR)       1.0              0.0          not both 0.0
-     * SCALE (SC)       not both 1.0         0.0              0.0
-     * TR | SC          not both 1.0         0.0          not both 0.0
-     * SHEAR (SH)           0.0          not both 0.0         0.0
-     * TR | SH              0.0          not both 0.0     not both 0.0
-     * SC | SH          not both 0.0     not both 0.0         0.0
-     * TR | SC | SH     not both 0.0     not both 0.0     not both 0.0
-     * 
- */ - protected void updateState() { - updateState2D(); - } - - /* - * This variant of the method is for cases where we know the 3D elements - * are set to identity... - */ - protected void updateState2D() { - if (mxy == 0.0 && myx == 0.0) { - if (mxx == 1.0 && myy == 1.0) { - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_IDENTITY; - type = TYPE_IDENTITY; - } else { - state = APPLY_TRANSLATE; - type = TYPE_TRANSLATION; - } - } else { - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SCALE; - } else { - state = (APPLY_SCALE | APPLY_TRANSLATE); - } - type = TYPE_UNKNOWN; - } - } else { - if (mxx == 0.0 && myy == 0.0) { - if (mxt == 0.0 && myt == 0.0) { - state = APPLY_SHEAR; - } else { - state = (APPLY_SHEAR | APPLY_TRANSLATE); - } - } else { - if (mxt == 0.0 && myt == 0.0) { - state = (APPLY_SHEAR | APPLY_SCALE); - } else { - state = (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE); - } - } - type = TYPE_UNKNOWN; - } - } - - /** - * Inverse transforms an array of single precision coordinates by this - * transform using the specified state type. - */ - private void doInverseTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts, - int thestate) throws NoninvertibleTransformException { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - double det; - if (dstPts == srcPts && dstOff > srcOff - && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - // assert(APPLY_3D was dealt with at a higher level) - switch (thestate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++] - Mxt; - double y = srcPts[srcOff++] - Myt; - dstPts[dstOff++] = (float) ((x * Myy - y * Mxy) / det); - dstPts[dstOff++] = (float) ((y * Mxx - x * Myx) / det); - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - det = Mxx * Myy - Mxy * Myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (float) ((x * Myy - y * Mxy) / det); - dstPts[dstOff++] = (float) ((y * Mxx - x * Myx) / det); - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++] - Mxt; - dstPts[dstOff++] = (float) ((srcPts[srcOff++] - Myt) / Myx); - dstPts[dstOff++] = (float) (x / Mxy); - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - if (Mxy == 0.0 || Myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (srcPts[srcOff++] / Myx); - dstPts[dstOff++] = (float) (x / Mxy); - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - dstPts[dstOff++] = (float) ((srcPts[srcOff++] - Mxt) / Mxx); - dstPts[dstOff++] = (float) ((srcPts[srcOff++] - Myt) / Myy); - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - if (Mxx == 0.0 || Myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (srcPts[srcOff++] / Mxx); - dstPts[dstOff++] = (float) (srcPts[srcOff++] / Myy); - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (srcPts[srcOff++] - Mxt); - dstPts[dstOff++] = (float) (srcPts[srcOff++] - Myt); - } - return; - case (APPLY_IDENTITY): - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, - numPts * 2); - } - return; - } - - /* NOTREACHED */ - } - - private void doTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts, int thestate) { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - if (dstPts == srcPts && dstOff > srcOff - && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - // Note that this method also works for 3D transforms since the - // mxz and myz matrix elements get multiplied by z (0.0) and the - // mzx, mzy, mzz, and mzt elements only get used to calculate - // the resulting Z coordinate, which we drop (ignore). - switch (thestate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = Mxx * x + Mxy * y + Mxt; - dstPts[dstOff++] = Myx * x + Myy * y + Myt; - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = Mxx * x + Mxy * y; - dstPts[dstOff++] = Myx * x + Myy * y; - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = Mxy * srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = Myx * x + Myt; - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = Mxy * srcPts[srcOff++]; - dstPts[dstOff++] = Myx * x; - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = Mxx * srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = Myy * srcPts[srcOff++] + Myt; - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - while (--numPts >= 0) { - dstPts[dstOff++] = Mxx * srcPts[srcOff++]; - dstPts[dstOff++] = Myy * srcPts[srcOff++]; - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = srcPts[srcOff++] + Mxt; - dstPts[dstOff++] = srcPts[srcOff++] + Myt; - } - return; - case (APPLY_IDENTITY): - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, - numPts * 2); - } - return; - } - - /* NOTREACHED */ - } - - private void doTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts, int thestate) { - double Mxx, Mxy, Mxt, Myx, Myy, Myt; // For caching - if (dstPts == srcPts && dstOff > srcOff - && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - // Note that this method also works for 3D transforms since the - // mxz and myz matrix elements get multiplied by z (0.0) and the - // mzx, mzy, mzz, and mzt elements only get used to calculate - // the resulting Z coordinate, which we drop (ignore). - switch (thestate) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxx * x + Mxy * y + Mxt); - dstPts[dstOff++] = (float) (Myx * x + Myy * y + Myt); - } - return; - case (APPLY_SHEAR | APPLY_SCALE): - Mxx = mxx; - Mxy = mxy; - Myx = myx; - Myy = myy; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - double y = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxx * x + Mxy * y); - dstPts[dstOff++] = (float) (Myx * x + Myy * y); - } - return; - case (APPLY_SHEAR | APPLY_TRANSLATE): - Mxy = mxy; - Mxt = mxt; - Myx = myx; - Myt = myt; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxy * srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (Myx * x + Myt); - } - return; - case (APPLY_SHEAR): - Mxy = mxy; - Myx = myx; - while (--numPts >= 0) { - double x = srcPts[srcOff++]; - dstPts[dstOff++] = (float) (Mxy * srcPts[srcOff++]); - dstPts[dstOff++] = (float) (Myx * x); - } - return; - case (APPLY_SCALE | APPLY_TRANSLATE): - Mxx = mxx; - Mxt = mxt; - Myy = myy; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (Mxx * srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (Myy * srcPts[srcOff++] + Myt); - } - return; - case (APPLY_SCALE): - Mxx = mxx; - Myy = myy; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (Mxx * srcPts[srcOff++]); - dstPts[dstOff++] = (float) (Myy * srcPts[srcOff++]); - } - return; - case (APPLY_TRANSLATE): - Mxt = mxt; - Myt = myt; - while (--numPts >= 0) { - dstPts[dstOff++] = (float) (srcPts[srcOff++] + Mxt); - dstPts[dstOff++] = (float) (srcPts[srcOff++] + Myt); - } - return; - case (APPLY_IDENTITY): - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, - numPts * 2); - } - return; - } - - /* NOTREACHED */ - } - - private BaseBounds inversTransform2DBounds(RectBounds src, - RectBounds dst) throws NoninvertibleTransformException { - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - double det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - double x1 = src.getMinX() - mxt; - double y1 = src.getMinY() - myt; - double x2 = src.getMaxX() - mxt; - double y2 = src.getMaxY() - myt; - dst.setBoundsAndSort((float) ((x1 * myy - y1 * mxy) / det), - (float) ((y1 * mxx - x1 * myx) / det), - (float) ((x2 * myy - y2 * mxy) / det), - (float) ((y2 * mxx - x2 * myx) / det)); - dst.add((float) ((x2 * myy - y1 * mxy) / det), - (float) ((y1 * mxx - x2 * myx) / det)); - dst.add((float) ((x1 * myy - y2 * mxy) / det), - (float) ((y2 * mxx - x1 * myx) / det)); - return dst; - case (APPLY_SHEAR | APPLY_TRANSLATE): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.setBoundsAndSort((float) ((src.getMinY() - myt) / myx), - (float) ((src.getMinX() - mxt) / mxy), - (float) ((src.getMaxY() - myt) / myx), - (float) ((src.getMaxX() - mxt) / mxy)); - break; - case (APPLY_SHEAR): - if (mxy == 0.0 || myx == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.setBoundsAndSort((float) (src.getMinY() / myx), - (float) (src.getMinX() / mxy), - (float) (src.getMaxY() / myx), - (float) (src.getMaxX() / mxy)); - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.setBoundsAndSort((float) ((src.getMinX() - mxt) / mxx), - (float) ((src.getMinY() - myt) / myy), - (float) ((src.getMaxX() - mxt) / mxx), - (float) ((src.getMaxY() - myt) / myy)); - break; - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst.setBoundsAndSort((float) (src.getMinX() / mxx), - (float) (src.getMinY() / myy), - (float) (src.getMaxX() / mxx), - (float) (src.getMaxY() / myy)); - break; - case (APPLY_TRANSLATE): - dst.setBounds((float) (src.getMinX() - mxt), - (float) (src.getMinY() - myt), - (float) (src.getMaxX() - mxt), - (float) (src.getMaxY() - myt)); - break; - case (APPLY_IDENTITY): - if (dst != src) { - dst.setBounds(src); - } - break; - } - return dst; - } - - // Note: Only use this method if src or dst is a 3D bounds - private BaseBounds inversTransform3DBounds(BaseBounds src, - BaseBounds dst) throws NoninvertibleTransformException { - switch (state) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR): - double det = mxx * myy - mxy * myx; - if (det == 0 || Math.abs(det) <= Double.MIN_VALUE) { - throw new NoninvertibleTransformException("Determinant is " - + det); - } - double x1 = src.getMinX() - mxt; - double y1 = src.getMinY() - myt; - double z1 = src.getMinZ(); - double x2 = src.getMaxX() - mxt; - double y2 = src.getMaxY() - myt; - double z2 = src.getMaxZ(); - dst = dst.deriveWithNewBoundsAndSort((float) ((x1 * myy - - y1 * mxy) - / det), - (float) ((y1 * mxx - - x1 * myx) - / det), - (float) (z1 / det), - (float) ((x2 * myy - - y2 * mxy) - / det), - (float) ((y2 * mxx - - x2 * myx) - / det), - (float) (z2 / det)); - dst.add((float) ((x2 * myy - y1 * mxy) / det), - (float) ((y1 * mxx - x2 * myx) / det), 0); - dst.add((float) ((x1 * myy - y2 * mxy) / det), - (float) ((y2 * mxx - x1 * myx) / det), 0); - return dst; - case (APPLY_SCALE | APPLY_TRANSLATE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst = dst.deriveWithNewBoundsAndSort((float) ((src.getMinX() - - mxt) - / mxx), - (float) ((src.getMinY() - - myt) - / myy), - src.getMinZ(), - (float) ((src.getMaxX() - - mxt) - / mxx), - (float) ((src.getMaxY() - - myt) - / myy), - src.getMaxZ()); - break; - case (APPLY_SCALE): - if (mxx == 0.0 || myy == 0.0) { - throw new NoninvertibleTransformException("Determinant is 0"); - } - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinX() - / mxx), - (float) (src.getMinY() - / myy), - src.getMinZ(), - (float) (src.getMaxX() - / mxx), - (float) (src.getMaxY() - / myy), - src.getMaxZ()); - break; - case (APPLY_TRANSLATE): - dst = dst.deriveWithNewBounds((float) (src.getMinX() - mxt), - (float) (src.getMinY() - myt), - src.getMinZ(), - (float) (src.getMaxX() - mxt), - (float) (src.getMaxY() - myt), - src.getMaxZ()); - break; - case (APPLY_IDENTITY): - if (dst != src) { - dst = dst.deriveWithNewBounds(src); - } - break; - } - return dst; - } - - private BaseBounds transform2DBounds(RectBounds src, RectBounds dst) { - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - double x1 = src.getMinX(); - double y1 = src.getMinY(); - double x2 = src.getMaxX(); - double y2 = src.getMaxY(); - dst.setBoundsAndSort((float) (x1 * mxx + y1 * mxy), - (float) (x1 * myx + y1 * myy), - (float) (x2 * mxx + y2 * mxy), - (float) (x2 * myx + y2 * myy)); - dst.add((float) (x1 * mxx + y2 * mxy), - (float) (x1 * myx + y2 * myy)); - dst.add((float) (x2 * mxx + y1 * mxy), - (float) (x2 * myx + y1 * myy)); - dst.setBounds((float) (dst.getMinX() + mxt), - (float) (dst.getMinY() + myt), - (float) (dst.getMaxX() + mxt), - (float) (dst.getMaxY() + myt)); - break; - case (APPLY_SHEAR | APPLY_TRANSLATE): - dst.setBoundsAndSort((float) (src.getMinY() * mxy + mxt), - (float) (src.getMinX() * myx + myt), - (float) (src.getMaxY() * mxy + mxt), - (float) (src.getMaxX() * myx + myt)); - break; - case (APPLY_SHEAR): - dst.setBoundsAndSort((float) (src.getMinY() * mxy), - (float) (src.getMinX() * myx), - (float) (src.getMaxY() * mxy), - (float) (src.getMaxX() * myx)); - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - dst.setBoundsAndSort((float) (src.getMinX() * mxx + mxt), - (float) (src.getMinY() * myy + myt), - (float) (src.getMaxX() * mxx + mxt), - (float) (src.getMaxY() * myy + myt)); - break; - case (APPLY_SCALE): - dst.setBoundsAndSort((float) (src.getMinX() * mxx), - (float) (src.getMinY() * myy), - (float) (src.getMaxX() * mxx), - (float) (src.getMaxY() * myy)); - break; - case (APPLY_TRANSLATE): - dst.setBounds((float) (src.getMinX() + mxt), - (float) (src.getMinY() + myt), - (float) (src.getMaxX() + mxt), - (float) (src.getMaxY() + myt)); - break; - case (APPLY_IDENTITY): - if (src != dst) { - dst.setBounds(src); - } - break; - } - return dst; - } - - // Note: Only use this method if src or dst is a 3D bounds - private BaseBounds transform3DBounds(BaseBounds src, BaseBounds dst) { - switch (state & APPLY_2D_MASK) { - default: - stateError(); - /* NOTREACHED */ - // Note: Assuming mxz = myz = mzx = mzy = mzt 0 - case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): - /* NOBREAK */ - case (APPLY_SHEAR | APPLY_SCALE): - double x1 = src.getMinX(); - double y1 = src.getMinY(); - double z1 = src.getMinZ(); - double x2 = src.getMaxX(); - double y2 = src.getMaxY(); - double z2 = src.getMaxZ(); - dst.setBoundsAndSort((float) (x1 * mxx + y1 * mxy), - (float) (x1 * myx + y1 * myy), (float) z1, - (float) (x2 * mxx + y2 * mxy), - (float) (x2 * myx + y2 * myy), (float) z2); - dst.add((float) (x1 * mxx + y2 * mxy), - (float) (x1 * myx + y2 * myy), 0); - dst.add((float) (x2 * mxx + y1 * mxy), - (float) (x2 * myx + y1 * myy), 0); - dst.deriveWithNewBounds((float) (dst.getMinX() + mxt), - (float) (dst.getMinY() + myt), - dst.getMinZ(), - (float) (dst.getMaxX() + mxt), - (float) (dst.getMaxY() + myt), - dst.getMaxZ()); - break; - case (APPLY_SHEAR | APPLY_TRANSLATE): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinY() - * mxy + mxt), - (float) (src.getMinX() - * myx + myt), - src.getMinZ(), - (float) (src.getMaxY() - * mxy + mxt), - (float) (src.getMaxX() - * myx + myt), - src.getMaxZ()); - break; - case (APPLY_SHEAR): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinY() - * mxy), - (float) (src.getMinX() - * myx), - src.getMinZ(), - (float) (src.getMaxY() - * mxy), - (float) (src.getMaxX() - * myx), - src.getMaxZ()); - break; - case (APPLY_SCALE | APPLY_TRANSLATE): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinX() - * mxx + mxt), - (float) (src.getMinY() - * myy + myt), - src.getMinZ(), - (float) (src.getMaxX() - * mxx + mxt), - (float) (src.getMaxY() - * myy + myt), - src.getMaxZ()); - break; - case (APPLY_SCALE): - dst = dst.deriveWithNewBoundsAndSort((float) (src.getMinX() - * mxx), - (float) (src.getMinY() - * myy), - src.getMinZ(), - (float) (src.getMaxX() - * mxx), - (float) (src.getMaxY() - * myy), - src.getMaxZ()); - break; - case (APPLY_TRANSLATE): - dst = dst.deriveWithNewBounds((float) (src.getMinX() + mxt), - (float) (src.getMinY() + myt), - src.getMinZ(), - (float) (src.getMaxX() + mxt), - (float) (src.getMaxY() + myt), - src.getMaxZ()); - break; - case (APPLY_IDENTITY): - if (src != dst) { - dst = dst.deriveWithNewBounds(src); - } - break; - } - return dst; - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/BaseTransform.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/BaseTransform.java deleted file mode 100644 index 31a7c23..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/BaseTransform.java +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Point2D; -import com.javafx.experiments.utils3d.geom.Rectangle; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public abstract class BaseTransform implements CanTransformVec3d { - public static final BaseTransform IDENTITY_TRANSFORM = new Identity(); - - public static enum Degree { - IDENTITY, - TRANSLATE_2D, - AFFINE_2D, - TRANSLATE_3D, - AFFINE_3D, - } - - /* - * This constant is only useful for a cached type field. - * It indicates that the type has been decached and must be recalculated. - */ - protected static final int TYPE_UNKNOWN = -1; - - /** - * This constant indicates that the transform defined by this object is an - * identity transform. An identity transform is one in which the output - * coordinates are always the same as the input coordinates. If this - * transform is anything other than the identity transform, the type will - * either be the constant GENERAL_TRANSFORM or a combination of the - * appropriate flag bits for the various coordinate conversions that this - * transform performs. - * - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_IDENTITY = 0; - - /** - * This flag bit indicates that the transform defined by this object - * performs a translation in addition to the conversions indicated by other - * flag bits. A translation moves the coordinates by a constant amount in x - * and y without changing the length or angle of vectors. - * - * @see #TYPE_IDENTITY - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_TRANSLATION = 1; - - /** - * This flag bit indicates that the transform defined by this object - * performs a uniform scale in addition to the conversions indicated by - * other flag bits. A uniform scale multiplies the length of vectors by the - * same amount in both the x and y directions without changing the angle - * between vectors. This flag bit is mutually exclusive with the - * TYPE_GENERAL_SCALE flag. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_UNIFORM_SCALE = 2; - - /** - * This flag bit indicates that the transform defined by this object - * performs a general scale in addition to the conversions indicated by - * other flag bits. A general scale multiplies the length of vectors by - * different amounts in the x and y directions without changing the angle - * between perpendicular vectors. This flag bit is mutually exclusive with - * the TYPE_UNIFORM_SCALE flag. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_GENERAL_SCALE = 4; - - /** - * This constant is a bit mask for any of the scale flag bits. - * - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - */ - public static final int TYPE_MASK_SCALE = (TYPE_UNIFORM_SCALE - | TYPE_GENERAL_SCALE); - - /** - * This flag bit indicates that the transform defined by this object - * performs a mirror image flip about some axis which changes the normally - * right handed coordinate system into a left handed system in addition to - * the conversions indicated by other flag bits. A right handed coordinate - * system is one where the positive X axis rotates counterclockwise to - * overlay the positive Y axis similar to the direction that the fingers on - * your right hand curl when you stare end on at your thumb. A left handed - * coordinate system is one where the positive X axis rotates clockwise to - * overlay the positive Y axis similar to the direction that the fingers on - * your left hand curl. There is no mathematical way to determine the angle - * of the original flipping or mirroring transformation since all angles of - * flip are identical given an appropriate adjusting rotation. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_FLIP = 64; - /* NOTE: TYPE_FLIP was added after GENERAL_TRANSFORM was in public - * circulation and the flag bits could no longer be conveniently - * renumbered without introducing binary incompatibility in outside - * code. - */ - - /** - * This flag bit indicates that the transform defined by this object - * performs a quadrant rotation by some multiple of 90 degrees in addition - * to the conversions indicated by other flag bits. A rotation changes the - * angles of vectors by the same amount regardless of the original direction - * of the vector and without changing the length of the vector. This flag - * bit is mutually exclusive with the TYPE_GENERAL_ROTATION flag. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_QUADRANT_ROTATION = 8; - - /** - * This flag bit indicates that the transform defined by this object - * performs a rotation by an arbitrary angle in addition to the conversions - * indicated by other flag bits. A rotation changes the angles of vectors by - * the same amount regardless of the original direction of the vector and - * without changing the length of the vector. This flag bit is mutually - * exclusive with the TYPE_QUADRANT_ROTATION flag. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - * @see #getType - */ - public static final int TYPE_GENERAL_ROTATION = 16; - - /** - * This constant is a bit mask for any of the rotation flag bits. - * - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - */ - public static final int TYPE_MASK_ROTATION = (TYPE_QUADRANT_ROTATION - | TYPE_GENERAL_ROTATION); - - /** - * This constant indicates that the transform defined by this object - * performs an arbitrary conversion of the input coordinates. If this - * transform can be classified by any of the above constants, the type will - * either be the constant TYPE_IDENTITY or a combination of the appropriate - * flag bits for the various coordinate conversions that this transform - * performs. - * - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_FLIP - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #getType - */ - public static final int TYPE_GENERAL_TRANSFORM = 32; - - public static final int TYPE_AFFINE2D_MASK = (TYPE_TRANSLATION - | TYPE_UNIFORM_SCALE - | TYPE_GENERAL_SCALE - | TYPE_QUADRANT_ROTATION - | TYPE_GENERAL_ROTATION - | TYPE_GENERAL_TRANSFORM - | TYPE_FLIP); - - public static final int TYPE_AFFINE_3D = 128; - - /* - * Convenience method used internally to throw exceptions when - * an operation of degree higher than AFFINE_2D is attempted. - */ - static void degreeError(Degree maxSupported) { - throw new InternalError("does not support higher than " + maxSupported - + " operations"); - } - - public static BaseTransform getInstance(BaseTransform tx) { - if (tx.isIdentity()) { - return IDENTITY_TRANSFORM; - } else if (tx.isTranslateOrIdentity()) { - return new Translate2D(tx); - } else if (tx.is2D()) { - return new Affine2D(tx); - } - return new Affine3D(tx); - } - - public static BaseTransform getInstance(double mxx, double mxy, double mxz, - double mxt, double myx, double myy, - double myz, double myt, double mzx, - double mzy, double mzz, - double mzt) { - if (mxz == 0.0 && myz == 0.0 && mzx == 0.0 && mzy == 0.0 && mzz == 1.0 - && mzt == 0.0) { - return getInstance(mxx, myx, mxy, myy, mxt, myt); - } else { - return new Affine3D(mxx, mxy, mxz, mxt, myx, myy, myz, myt, mzx, - mzy, mzz, mzt); - } - } - - public static BaseTransform getInstance(double mxx, double myx, double mxy, - double myy, double mxt, - double myt) { - if (mxx == 1.0 && myx == 0.0 && mxy == 0.0 && myy == 1.0) { - return getTranslateInstance(mxt, myt); - } else { - return new Affine2D(mxx, myx, mxy, myy, mxt, myt); - } - } - - public static BaseTransform getTranslateInstance(double mxt, double myt) { - if (mxt == 0.0 && myt == 0.0) { - return IDENTITY_TRANSFORM; - } else { - return new Translate2D(mxt, myt); - } - } - - public static BaseTransform getScaleInstance(double mxx, double myy) { - return getInstance(mxx, 0, 0, myy, 0, 0); - } - - public static BaseTransform getRotateInstance(double theta, double x, - double y) { - Affine2D a = new Affine2D(); - a.setToRotation(theta, x, y); - return a; - } - - public abstract Degree getDegree(); - - /** - * Retrieves the flag bits describing the conversion properties of this - * transform. The return value is either one of the constants TYPE_IDENTITY - * or TYPE_GENERAL_TRANSFORM, or a combination of the appriopriate flag - * bits. A valid combination of flag bits is an exclusive OR operation that - * can combine the TYPE_TRANSLATION flag bit in addition to either of the - * TYPE_UNIFORM_SCALE or TYPE_GENERAL_SCALE flag bits as well as either of - * the TYPE_QUADRANT_ROTATION or TYPE_GENERAL_ROTATION flag bits. - * - * @return the OR combination of any of the indicated flags that apply to - * this transform - * @see #TYPE_IDENTITY - * @see #TYPE_TRANSLATION - * @see #TYPE_UNIFORM_SCALE - * @see #TYPE_GENERAL_SCALE - * @see #TYPE_QUADRANT_ROTATION - * @see #TYPE_GENERAL_ROTATION - * @see #TYPE_GENERAL_TRANSFORM - */ - public abstract int getType(); - - public abstract boolean isIdentity(); - - public abstract boolean isTranslateOrIdentity(); - - public abstract boolean is2D(); - - public abstract double getDeterminant(); - - public double getMxx() { - return 1.0; - } - - public double getMxy() { - return 0.0; - } - - public double getMxz() { - return 0.0; - } - - public double getMxt() { - return 0.0; - } - - public double getMyx() { - return 0.0; - } - - public double getMyy() { - return 1.0; - } - - public double getMyz() { - return 0.0; - } - - public double getMyt() { - return 0.0; - } - - public double getMzx() { - return 0.0; - } - - public double getMzy() { - return 0.0; - } - - public double getMzz() { - return 1.0; - } - - public double getMzt() { - return 0.0; - } - - public abstract Point2D transform(Point2D src, Point2D dst); - - public abstract Point2D inverseTransform(Point2D src, - Point2D dst) throws NoninvertibleTransformException; - - @Override - public abstract Vec3d transform(Vec3d src, Vec3d dst); - - public abstract Vec3d deltaTransform(Vec3d src, Vec3d dst); - - public abstract Vec3d inverseTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException; - - public abstract Vec3d inverseDeltaTransform(Vec3d src, - Vec3d dst) throws NoninvertibleTransformException; - - public abstract void transform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts); - - public abstract void transform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts); - - public abstract void transform(float[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts); - - public abstract void transform(double[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts); - - public abstract void deltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, int numPts); - - public abstract void deltaTransform(double[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int numPts); - - public abstract void inverseTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int numPts) throws NoninvertibleTransformException; - - public abstract void inverseDeltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int numPts) throws NoninvertibleTransformException; - - public abstract void inverseTransform(double[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int numPts) throws NoninvertibleTransformException; - - public abstract BaseBounds transform(BaseBounds bounds, BaseBounds result); - - public abstract void transform(Rectangle rect, Rectangle result); - - public abstract BaseBounds inverseTransform(BaseBounds bounds, - BaseBounds result) throws NoninvertibleTransformException; - - public abstract void inverseTransform(Rectangle rect, - Rectangle result) throws NoninvertibleTransformException; - - public abstract void setToIdentity(); - - public abstract void setTransform(BaseTransform xform); - - /** - * This function inverts the {@code BaseTransform} in place. All current - * implementations can support their own inverted form, and that should - * likely remain true in the future as well. - */ - public abstract void invert() throws NoninvertibleTransformException; - - /** - * This function is only guaranteed to succeed if the transform is of degree - * AFFINE2D or less and the matrix parameters specified came from this same - * instance. In practice, they will also tend to succeed if they specify a - * transform of Degree less than or equal to the Degree of this instance as - * well, but the intent of this method is to restore the transform that had - * been read out of this transform into local variables. - */ - public abstract void restoreTransform(double mxx, double myx, double mxy, - double myy, double mxt, double myt); - - /** - * This function is only guaranteed to succeed if the matrix parameters - * specified came from this same instance. In practice, they will also tend - * to succeed if they specify a transform of Degree less than or equal to - * the Degree of this instance as well, but the intent of this method is to - * restore the transform that had been read out of this transform into local - * variables. - */ - public abstract void restoreTransform(double mxx, double mxy, double mxz, - double mxt, double myx, double myy, - double myz, double myt, double mzx, - double mzy, double mzz, double mzt); - - public abstract BaseTransform deriveWithTranslation(double mxt, double myt); - - public abstract BaseTransform deriveWithTranslation(double mxt, double myt, - double mzt); - - public abstract BaseTransform deriveWithScale(double mxx, double myy, - double mzz); - - public abstract BaseTransform deriveWithRotation(double theta, double axisX, - double axisY, - double axisZ); - - public abstract BaseTransform deriveWithPreTranslation(double mxt, - double myt); - - public abstract BaseTransform deriveWithConcatenation(double mxx, - double myx, - double mxy, - double myy, - double mxt, - double myt); - - public abstract BaseTransform deriveWithConcatenation(double mxx, - double mxy, - double mxz, - double mxt, - double myx, - double myy, - double myz, - double myt, - double mzx, - double mzy, - double mzz, - double mzt); - - public abstract BaseTransform deriveWithPreConcatenation(BaseTransform transform); - - public abstract BaseTransform deriveWithConcatenation(BaseTransform tx); - - public abstract BaseTransform deriveWithNewTransform(BaseTransform tx); - - /** - * This function always returns a new object, unless the transform is an - * identity transform in which case it might return the {@code Identity} - * singleton. - * - * @return a new transform representing the inverse of this transform. - */ - public abstract BaseTransform createInverse() throws NoninvertibleTransformException; - - public abstract BaseTransform copy(); - - /** - * Returns the hashcode for this transform. - * - * @return a hash code for this transform. - */ - @Override - public int hashCode() { - if (isIdentity()) { - return 0; - } - long bits = 0; - bits = bits * 31 + Double.doubleToLongBits(getMzz()); - bits = bits * 31 + Double.doubleToLongBits(getMzy()); - bits = bits * 31 + Double.doubleToLongBits(getMzx()); - bits = bits * 31 + Double.doubleToLongBits(getMyz()); - bits = bits * 31 + Double.doubleToLongBits(getMxz()); - bits = bits * 31 + Double.doubleToLongBits(getMyy()); - bits = bits * 31 + Double.doubleToLongBits(getMyx()); - bits = bits * 31 + Double.doubleToLongBits(getMxy()); - bits = bits * 31 + Double.doubleToLongBits(getMxx()); - bits = bits * 31 + Double.doubleToLongBits(getMzt()); - bits = bits * 31 + Double.doubleToLongBits(getMyt()); - bits = bits * 31 + Double.doubleToLongBits(getMxt()); - return (((int) bits) ^ ((int) (bits >> 32))); - } - - /** - * Returns true if this BaseTransform represents - * the same coordinate transform as the specified argument. - * - * @param obj - * the Object to test for equality with this - * BaseTransform - * @return true if obj equals this - * BaseTransform object; false otherwise. - */ - @Override - public boolean equals(Object obj) { - if (!(obj instanceof BaseTransform)) { - return false; - } - - BaseTransform a = (BaseTransform) obj; - - return (getMxx() == a.getMxx() && getMxy() == a.getMxy() - && getMxz() == a.getMxz() && getMxt() == a.getMxt() - && getMyx() == a.getMyx() && getMyy() == a.getMyy() - && getMyz() == a.getMyz() && getMyt() == a.getMyt() - && getMzx() == a.getMzx() && getMzy() == a.getMzy() - && getMzz() == a.getMzz() && getMzt() == a.getMzt()); - } - - static Point2D makePoint(Point2D src, Point2D dst) { - if (dst == null) { - dst = new Point2D(); - } - return dst; - } - - static final double EPSILON_ABSOLUTE = 1.0e-5; - - public static boolean almostZero(double a) { - return ((a < EPSILON_ABSOLUTE) && (a > -EPSILON_ABSOLUTE)); - } - - /** - * Returns the matrix elements and degree of this transform as a string. - * - * @return the matrix elements and degree of this transform - */ - @Override - public String toString() { - return "Matrix: degree " + getDegree() + "\n" + getMxx() + ", " - + getMxy() + ", " + getMxz() + ", " + getMxt() + "\n" + getMyx() - + ", " + getMyy() + ", " + getMyz() + ", " + getMyt() + "\n" - + getMzx() + ", " + getMzy() + ", " + getMzz() + ", " + getMzt() - + "\n"; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/CanTransformVec3d.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/CanTransformVec3d.java deleted file mode 100644 index 88948d2..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/CanTransformVec3d.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.Vec3d; - -public interface CanTransformVec3d { - - public Vec3d transform(Vec3d point, Vec3d pointOut); - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Identity.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Identity.java deleted file mode 100644 index e8ec1f6..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Identity.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Point2D; -import com.javafx.experiments.utils3d.geom.Rectangle; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public final class Identity extends BaseTransform { - @Override - public BaseTransform copy() { - return this; - } - - @Override - public BaseTransform createInverse() { - return this; - } - - @Override - public void deltaTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public void deltaTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Vec3d deltaTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - return new Vec3d(src); - } - dst.set(src); - return dst; - } - - @Override - public BaseTransform deriveWithConcatenation(BaseTransform tx) { - return getInstance(tx); - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double myx, - double mxy, double myy, - double mxt, double myt) { - return getInstance(mxx, myx, mxy, myy, mxt, myt); - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double mxy, - double mxz, double mxt, - double myx, double myy, - double myz, double myt, - double mzx, double mzy, - double mzz, double mzt) { - return getInstance(mxx, mxy, mxz, mxt, myx, myy, myz, myt, mzx, mzy, - mzz, mzt); - } - - @Override - public BaseTransform deriveWithNewTransform(BaseTransform tx) { - return getInstance(tx); - } - - @Override - public BaseTransform deriveWithPreConcatenation(BaseTransform tx) { - return getInstance(tx); - } - - @Override - public BaseTransform deriveWithPreTranslation(double mxt, double myt) { - return Translate2D.getInstance(mxt, myt); - } - - @Override - public BaseTransform deriveWithRotation(double theta, double axisX, - double axisY, double axisZ) { - if (theta == 0.0) { - return this; - } - if (almostZero(axisX) && almostZero(axisY)) { - if (axisZ == 0.0) { - return this; - } - Affine2D a = new Affine2D(); - if (axisZ > 0) { - a.rotate(theta); - } else if (axisZ < 0) { - a.rotate(-theta); - } - return a; - } - Affine3D a = new Affine3D(); - a.rotate(theta, axisX, axisY, axisZ); - return a; - } - - @Override - public BaseTransform deriveWithScale(double mxx, double myy, double mzz) { - if (mzz == 1.0) { - if (mxx == 1.0 && myy == 1.0) { - return this; - } - Affine2D a = new Affine2D(); - a.scale(mxx, myy); - return a; - } - Affine3D a = new Affine3D(); - a.scale(mxx, myy, mzz); - return a; - - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt) { - return Translate2D.getInstance(mxt, myt); - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt, - double mzt) { - if (mzt == 0.0) { - if (mxt == 0.0 && myt == 0.0) { - return this; - } - return new Translate2D(mxt, myt); - } - Affine3D a = new Affine3D(); - a.translate(mxt, myt, mzt); - return a; - } - - @Override - public boolean equals(Object obj) { - return (obj instanceof BaseTransform - && ((BaseTransform) obj).isIdentity()); - } - - @Override - public Degree getDegree() { - return Degree.IDENTITY; - } - - @Override - public double getDeterminant() { - return 1.0; - } - - @Override - public int getType() { - return TYPE_IDENTITY; - } - - @Override - public int hashCode() { - return 0; - } - - @Override - public void inverseDeltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Vec3d inverseDeltaTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - return new Vec3d(src); - } - dst.set(src); - return dst; - } - - @Override - public BaseBounds inverseTransform(BaseBounds bounds, BaseBounds result) { - if (result != bounds) { - result = result.deriveWithNewBounds(bounds); - } - return result; - } - - @Override - public void inverseTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public void inverseTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Point2D inverseTransform(Point2D src, Point2D dst) { - if (dst == null) { - dst = makePoint(src, dst); - } - dst.setLocation(src); - return dst; - } - - @Override - public void inverseTransform(Rectangle rect, Rectangle result) { - if (result != rect) { - result.setBounds(rect); - } - } - - @Override - public Vec3d inverseTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - return new Vec3d(src); - } - dst.set(src); - return dst; - } - - @Override - public void invert() { - } - - @Override - public boolean is2D() { - return true; - } - - @Override - public boolean isIdentity() { - return true; - } - - @Override - public boolean isTranslateOrIdentity() { - return true; - } - - @Override - public void restoreTransform(double mxx, double myx, double mxy, double myy, - double mxt, double myt) { - if (mxx != 1.0 || myx != 0.0 || mxy != 0.0 || myy != 1.0 || mxt != 0.0 - || myt != 0.0) { - degreeError(Degree.IDENTITY); - } - } - - @Override - public void restoreTransform(double mxx, double mxy, double mxz, double mxt, - double myx, double myy, double myz, double myt, - double mzx, double mzy, double mzz, - double mzt) { - if (mxx != 1.0 || mxy != 0.0 || mxz != 0.0 || mxt != 0.0 || myx != 0.0 - || myy != 1.0 || myz != 0.0 || myt != 0.0 || mzx != 0.0 - || mzy != 0.0 || mzz != 1.0 || mzt != 0.0) { - degreeError(Degree.IDENTITY); - } - } - - @Override - public void setToIdentity() { - } - - @Override - public void setTransform(BaseTransform xform) { - if (!xform.isIdentity()) { - degreeError(Degree.IDENTITY); - } - } - - @Override - public String toString() { - return ("Identity[]"); - } - - @Override - public BaseBounds transform(BaseBounds bounds, BaseBounds result) { - if (result != bounds) { - result = result.deriveWithNewBounds(bounds); - } - return result; - } - - @Override - public void transform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public void transform(double[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = (float) srcPts[srcOff++]; - dstPts[dstOff++] = (float) srcPts[srcOff++]; - } - } - - @Override - public void transform(float[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++]; - dstPts[dstOff++] = srcPts[srcOff++]; - } - } - - @Override - public void transform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Point2D transform(Point2D src, Point2D dst) { - if (dst == null) { - dst = makePoint(src, dst); - } - dst.setLocation(src); - return dst; - } - - @Override - public void transform(Rectangle rect, Rectangle result) { - if (result != rect) { - result.setBounds(rect); - } - } - - @Override - public Vec3d transform(Vec3d src, Vec3d dst) { - if (dst == null) { - return new Vec3d(src); - } - dst.set(src); - return dst; - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/NoninvertibleTransformException.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/NoninvertibleTransformException.java deleted file mode 100644 index 466857e..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/NoninvertibleTransformException.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -/** - * The NoninvertibleTransformException class represents an - * exception that is thrown if an operation is performed requiring the inverse - * of a {@link com.javafx.experiments.utils3d.geom.transform.BaseTransform} - * object but the BaseTransform is in a non-invertible state. - * - * @version 1.25, 05/05/07 - */ - -public class NoninvertibleTransformException extends Exception { - private static final long serialVersionUID = 1L; - - /** - * Constructs an instance of NoninvertibleTransformException - * with the specified detail message. - * - * @param s - * the detail message - */ - public NoninvertibleTransformException(String s) { - super(s); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/SingularMatrixException.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/SingularMatrixException.java deleted file mode 100644 index d9a5db0..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/SingularMatrixException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -/** - * Indicates that inverse of a matrix can not be computed. - */ -public class SingularMatrixException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public SingularMatrixException() { - } - - public SingularMatrixException(String string) { - super(string); - } -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/TransformHelper.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/TransformHelper.java deleted file mode 100644 index f8331ee..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/TransformHelper.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public class TransformHelper { - - public static BaseBounds general3dBoundsTransform(CanTransformVec3d tx, - BaseBounds src, - BaseBounds dst, - Vec3d tempV3d) { - - if (tempV3d == null) { - tempV3d = new Vec3d(); - } - - double srcMinX = src.getMinX(); - double srcMinY = src.getMinY(); - double srcMinZ = src.getMinZ(); - double srcMaxX = src.getMaxX(); - double srcMaxY = src.getMaxY(); - double srcMaxZ = src.getMaxZ(); - - // TODO: Optimize... (RT-26884) - tempV3d.set(srcMaxX, srcMaxY, srcMaxZ); - tempV3d = tx.transform(tempV3d, tempV3d); - double minX = tempV3d.x; - double minY = tempV3d.y; - double minZ = tempV3d.z; - double maxX = tempV3d.x; - double maxY = tempV3d.y; - double maxZ = tempV3d.z; - - tempV3d.set(srcMinX, srcMaxY, srcMaxZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMinX, srcMinY, srcMaxZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMaxX, srcMinY, srcMaxZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMinX, srcMaxY, srcMinZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMaxX, srcMaxY, srcMinZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMinX, srcMinY, srcMinZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - tempV3d.set(srcMaxX, srcMinY, srcMinZ); - tempV3d = tx.transform(tempV3d, tempV3d); - if (tempV3d.x > maxX) { - maxX = tempV3d.x; - } - if (tempV3d.y > maxY) { - maxY = tempV3d.y; - } - if (tempV3d.z > maxZ) { - maxZ = tempV3d.z; - } - if (tempV3d.x < minX) { - minX = tempV3d.x; - } - if (tempV3d.y < minY) { - minY = tempV3d.y; - } - if (tempV3d.z < minZ) { - minZ = tempV3d.z; - } - - return dst.deriveWithNewBounds((float) minX, (float) minY, (float) minZ, - (float) maxX, (float) maxY, - (float) maxZ); - } - - private TransformHelper() { - } - -} diff --git a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Translate2D.java b/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Translate2D.java deleted file mode 100644 index d0d8cd0..0000000 --- a/gui/src/main/java/com/javafx/experiments/utils3d/geom/transform/Translate2D.java +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. - * All rights reserved. Use is subject to license terms. - * - * This file is available and licensed under the following license: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the distribution. - * - Neither the name of Oracle Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.javafx.experiments.utils3d.geom.transform; - -import com.javafx.experiments.utils3d.geom.BaseBounds; -import com.javafx.experiments.utils3d.geom.Point2D; -import com.javafx.experiments.utils3d.geom.Rectangle; -import com.javafx.experiments.utils3d.geom.Vec3d; - -public class Translate2D extends BaseTransform { - private static final long BASE_HASH; - static { - long bits = 0; - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzz()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzy()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzx()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMyz()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMxz()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMyy()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMyx()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMxy()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMxx()); - bits = bits * 31 + Double.doubleToLongBits(IDENTITY_TRANSFORM.getMzt()); - BASE_HASH = bits; - } - - public static BaseTransform getInstance(double mxt, double myt) { - if (mxt == 0.0 && myt == 0.0) { - return IDENTITY_TRANSFORM; - } else { - return new Translate2D(mxt, myt); - } - } - - static void transform(Rectangle rect, Rectangle result, double mxt, - double myt) { - int imxt = (int) mxt; - int imyt = (int) myt; - if (imxt == mxt && imyt == myt) { - result.setBounds(rect); - result.translate(imxt, imyt); - } else { - double x1 = rect.x + mxt; - double y1 = rect.y + myt; - double x2 = Math.ceil(x1 + rect.width); - double y2 = Math.ceil(y1 + rect.height); - x1 = Math.floor(x1); - y1 = Math.floor(y1); - result.setBounds((int) x1, (int) y1, (int) (x2 - x1), - (int) (y2 - y1)); - } - } - - // Round values to sane precision for printing - // Note that Math.sin(Math.PI) has an error of about 10^-16 - private static double _matround(double matval) { - return Math.rint(matval * 1E15) / 1E15; - } - - private double mxt; - - private double myt; - - public Translate2D(BaseTransform tx) { - if (!tx.isTranslateOrIdentity()) { - degreeError(Degree.TRANSLATE_2D); - } - this.mxt = tx.getMxt(); - this.myt = tx.getMyt(); - } - - public Translate2D(double tx, double ty) { - this.mxt = tx; - this.myt = ty; - } - - @Override - public BaseTransform copy() { - return new Translate2D(this.mxt, this.myt); - } - - @Override - public BaseTransform createInverse() { - if (isIdentity()) { - return IDENTITY_TRANSFORM; - } else { - return new Translate2D(-this.mxt, -this.myt); - } - } - - @Override - public void deltaTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public void deltaTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Vec3d deltaTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - dst.set(src); - return dst; - } - - @Override - public BaseTransform deriveWithConcatenation(BaseTransform tx) { - if (tx.isTranslateOrIdentity()) { - this.mxt += tx.getMxt(); - this.myt += tx.getMyt(); - return this; - } else if (tx.is2D()) { - return getInstance(tx.getMxx(), tx.getMyx(), tx.getMxy(), - tx.getMyy(), this.mxt + tx.getMxt(), - this.myt + tx.getMyt()); - } else { - Affine3D t3d = new Affine3D(tx); - t3d.preTranslate(this.mxt, this.myt, 0.0); - return t3d; - } - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double myx, - double mxy, double myy, - double mxt, double myt) { - if (mxx == 1.0 && myx == 0.0 && mxy == 0.0 && myy == 1.0) { - this.mxt += mxt; - this.myt += myt; - return this; - } else { - return new Affine2D(mxx, myx, mxy, myy, this.mxt + mxt, - this.myt + myt); - } - } - - @Override - public BaseTransform deriveWithConcatenation(double mxx, double mxy, - double mxz, double mxt, - double myx, double myy, - double myz, double myt, - double mzx, double mzy, - double mzz, double mzt) { - if (mxz == 0.0 && myz == 0.0 && mzx == 0.0 && mzy == 0.0 && mzz == 1.0 - && mzt == 0.0) { - return deriveWithConcatenation(mxx, myx, mxy, myy, mxt, myt); - } - - return new Affine3D(mxx, mxy, mxz, mxt + this.mxt, myx, myy, myz, - myt + this.myt, mzx, mzy, mzz, mzt); - } - - @Override - public BaseTransform deriveWithNewTransform(BaseTransform tx) { - if (tx.isTranslateOrIdentity()) { - this.mxt = tx.getMxt(); - this.myt = tx.getMyt(); - return this; - } else { - return getInstance(tx); - } - } - - @Override - public BaseTransform deriveWithPreConcatenation(BaseTransform tx) { - if (tx.isTranslateOrIdentity()) { - this.mxt += tx.getMxt(); - this.myt += tx.getMyt(); - return this; - } else if (tx.is2D()) { - Affine2D t2d = new Affine2D(tx); - t2d.translate(this.mxt, this.myt); - return t2d; - } else { - Affine3D t3d = new Affine3D(tx); - t3d.translate(this.mxt, this.myt, 0.0); - return t3d; - } - } - - @Override - public BaseTransform deriveWithPreTranslation(double mxt, double myt) { - this.mxt += mxt; - this.myt += myt; - return this; - } - - @Override - public BaseTransform deriveWithRotation(double theta, double axisX, - double axisY, double axisZ) { - if (theta == 0.0) { - return this; - } - if (almostZero(axisX) && almostZero(axisY)) { - if (axisZ == 0.0) { - return this; - } - Affine2D a = new Affine2D(); - a.translate(this.mxt, this.myt); - if (axisZ > 0) { - a.rotate(theta); - } else if (axisZ < 0) { - a.rotate(-theta); - } - return a; - } - Affine3D a = new Affine3D(); - a.translate(this.mxt, this.myt); - a.rotate(theta, axisX, axisY, axisZ); - return a; - } - - @Override - public BaseTransform deriveWithScale(double mxx, double myy, double mzz) { - if (mzz == 1.0) { - if (mxx == 1.0 && myy == 1.0) { - return this; - } - Affine2D a = new Affine2D(); - a.translate(this.mxt, this.myt); - a.scale(mxx, myy); - return a; - } - Affine3D a = new Affine3D(); - a.translate(this.mxt, this.myt); - a.scale(mxx, myy, mzz); - return a; - - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt) { - this.mxt += mxt; - this.myt += myt; - return this; - } - - @Override - public BaseTransform deriveWithTranslation(double mxt, double myt, - double mzt) { - if (mzt == 0.0) { - this.mxt += mxt; - this.myt += myt; - return this; - } - Affine3D a = new Affine3D(); - a.translate(this.mxt + mxt, this.myt + myt, mzt); - return a; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof BaseTransform) { - BaseTransform tx = (BaseTransform) obj; - return (tx.isTranslateOrIdentity() && tx.getMxt() == this.mxt - && tx.getMyt() == this.myt); - } - return false; - } - - @Override - public Degree getDegree() { - return Degree.TRANSLATE_2D; - } - - @Override - public double getDeterminant() { - return 1.0; - } - - @Override - public double getMxt() { - return mxt; - } - - @Override - public double getMyt() { - return myt; - } - - @Override - public int getType() { - return (mxt == 0.0 && myt == 0.0) ? TYPE_IDENTITY : TYPE_TRANSLATION; - } - - @Override - public int hashCode() { - if (isIdentity()) { - return 0; - } - long bits = BASE_HASH; - bits = bits * 31 + Double.doubleToLongBits(getMyt()); - bits = bits * 31 + Double.doubleToLongBits(getMxt()); - return (((int) bits) ^ ((int) (bits >> 32))); - } - - @Override - public void inverseDeltaTransform(float[] srcPts, int srcOff, - float[] dstPts, int dstOff, int numPts) { - if (srcPts != dstPts || srcOff != dstOff) { - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - } - } - - @Override - public Vec3d inverseDeltaTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - dst.set(src); - return dst; - } - - @Override - public BaseBounds inverseTransform(BaseBounds bounds, BaseBounds result) { - float minX = (float) (bounds.getMinX() - mxt); - float minY = (float) (bounds.getMinY() - myt); - float minZ = bounds.getMinZ(); - float maxX = (float) (bounds.getMaxX() - mxt); - float maxY = (float) (bounds.getMaxY() - myt); - float maxZ = bounds.getMaxZ(); - return result.deriveWithNewBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public void inverseTransform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - double tx = this.mxt; - double ty = this.myt; - if (dstPts == srcPts) { - if (dstOff > srcOff && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - if (dstOff == srcOff && tx == 0f && ty == 0f) { - return; - } - } - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++] - tx; - dstPts[dstOff++] = srcPts[srcOff++] - ty; - } - } - - @Override - public void inverseTransform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - float tx = (float) this.mxt; - float ty = (float) this.myt; - if (dstPts == srcPts) { - if (dstOff > srcOff && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - if (dstOff == srcOff && tx == 0.0f && ty == 0.0f) { - return; - } - } - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++] - tx; - dstPts[dstOff++] = srcPts[srcOff++] - ty; - } - } - - @Override - public Point2D inverseTransform(Point2D src, Point2D dst) { - if (dst == null) { - dst = makePoint(src, dst); - } - dst.setLocation((float) (src.x - mxt), (float) (src.y - myt)); - return dst; - } - - @Override - public void inverseTransform(Rectangle rect, Rectangle result) { - transform(rect, result, -mxt, -myt); - } - - @Override - public Vec3d inverseTransform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - dst.x = src.x - mxt; - dst.y = src.y - myt; - dst.z = src.z; - return dst; - } - - @Override - public void invert() { - this.mxt = -this.mxt; - this.myt = -this.myt; - } - - @Override - public boolean is2D() { - return true; - } - - @Override - public boolean isIdentity() { - return (mxt == 0.0 && myt == 0.0); - } - - @Override - public boolean isTranslateOrIdentity() { - return true; - } - - @Override - public void restoreTransform(double mxx, double myx, double mxy, double myy, - double mxt, double myt) { - if (mxx != 1.0 || myx != 0.0 || mxy != 0.0 || myy != 1.0) { - degreeError(Degree.TRANSLATE_2D); - } - this.mxt = mxt; - this.myt = myt; - } - - @Override - public void restoreTransform(double mxx, double mxy, double mxz, double mxt, - double myx, double myy, double myz, double myt, - double mzx, double mzy, double mzz, - double mzt) { - if (mxx != 1.0 || mxy != 0.0 || mxz != 0.0 || myx != 0.0 || myy != 1.0 - || myz != 0.0 || mzx != 0.0 || mzy != 0.0 || mzz != 1.0 - || mzt != 0.0) { - degreeError(Degree.TRANSLATE_2D); - } - this.mxt = mxt; - this.myt = myt; - } - - @Override - public void setToIdentity() { - this.mxt = this.myt = 0.0; - } - - @Override - public void setTransform(BaseTransform xform) { - if (!xform.isTranslateOrIdentity()) { - degreeError(Degree.TRANSLATE_2D); - } - this.mxt = xform.getMxt(); - this.myt = xform.getMyt(); - } - - @Override - public String toString() { - return ("Translate2D[" + _matround(mxt) + ", " + _matround(myt) + "]"); - } - - @Override - public BaseBounds transform(BaseBounds bounds, BaseBounds result) { - float minX = (float) (bounds.getMinX() + mxt); - float minY = (float) (bounds.getMinY() + myt); - float minZ = bounds.getMinZ(); - float maxX = (float) (bounds.getMaxX() + mxt); - float maxY = (float) (bounds.getMaxY() + myt); - float maxZ = bounds.getMaxZ(); - return result.deriveWithNewBounds(minX, minY, minZ, maxX, maxY, maxZ); - } - - @Override - public void transform(double[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - double tx = this.mxt; - double ty = this.myt; - if (dstPts == srcPts) { - if (dstOff > srcOff && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - if (dstOff == srcOff && tx == 0.0 && ty == 0.0) { - return; - } - } - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++] + tx; - dstPts[dstOff++] = srcPts[srcOff++] + ty; - } - } - - @Override - public void transform(double[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - double tx = this.mxt; - double ty = this.myt; - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = (float) (srcPts[srcOff++] + tx); - dstPts[dstOff++] = (float) (srcPts[srcOff++] + ty); - } - } - - @Override - public void transform(float[] srcPts, int srcOff, double[] dstPts, - int dstOff, int numPts) { - double tx = this.mxt; - double ty = this.myt; - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++] + tx; - dstPts[dstOff++] = srcPts[srcOff++] + ty; - } - } - - @Override - public void transform(float[] srcPts, int srcOff, float[] dstPts, - int dstOff, int numPts) { - float tx = (float) this.mxt; - float ty = (float) this.myt; - if (dstPts == srcPts) { - if (dstOff > srcOff && dstOff < srcOff + numPts * 2) { - // If the arrays overlap partially with the destination higher - // than the source and we transform the coordinates normally - // we would overwrite some of the later source coordinates - // with results of previous transformations. - // To get around this we use arraycopy to copy the points - // to their final destination with correct overwrite - // handling and then transform them in place in the new - // safer location. - System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); - // srcPts = dstPts; // They are known to be equal. - srcOff = dstOff; - } - if (dstOff == srcOff && tx == 0.0f && ty == 0.0f) { - return; - } - } - for (int i = 0; i < numPts; i++) { - dstPts[dstOff++] = srcPts[srcOff++] + tx; - dstPts[dstOff++] = srcPts[srcOff++] + ty; - } - } - - @Override - public Point2D transform(Point2D src, Point2D dst) { - if (dst == null) { - dst = makePoint(src, dst); - } - dst.setLocation((float) (src.x + mxt), (float) (src.y + myt)); - return dst; - } - - @Override - public void transform(Rectangle rect, Rectangle result) { - transform(rect, result, mxt, myt); - } - - @Override - public Vec3d transform(Vec3d src, Vec3d dst) { - if (dst == null) { - dst = new Vec3d(); - } - dst.x = src.x + mxt; - dst.y = src.y + myt; - dst.z = src.z; - return dst; - } -} diff --git a/gui/src/main/java/math/VectorMath.java b/gui/src/main/java/math/VectorMath.java deleted file mode 100644 index bddac01..0000000 --- a/gui/src/main/java/math/VectorMath.java +++ /dev/null @@ -1,75 +0,0 @@ -package math; - -import javax.vecmath.Vector3d; - -/** - * A class with helper vector functions. - * - * @author Brian Yao - */ -public class VectorMath { - - private static final double EPSILON = 1e-15; - - /** - * Returns the difference of two vectors. - * - * @param start - * The vector being subtracted. - * @param end - * The vector we are subtracting from. - * @return The difference end - start. - */ - public static Vector3d diff(Vector3d start, Vector3d end) { - Vector3d diff = new Vector3d(); - diff.sub(end, start); - return diff; - } - - /** - * Returns the parametric interpolation of two vectors for parameter 0 <= t - * <= 1. At t = 0 this returns the start, and at t = 1 returns the end. In - * general, this returns start + (end - start) * t. - * - * @param start - * The start vector (t = 0). - * @param end - * The end vector (t = 1). - * @param t - * The parameter (0 <= t <= 1). - * @return The interpolation at the parameter t. - */ - public static Vector3d interpolate(Vector3d start, Vector3d end, double t) { - Vector3d diff = diff(start, end); - diff.scale(t); - Vector3d newPoint = new Vector3d(); - newPoint.add(start, diff); - return newPoint; - } - - /** - * Returns true if the given vector has at least one component which is NaN. - * - * @param vector - * The vector whose components we are comparing to NaN. - * @return True if at least one component is NaN. - */ - public static boolean isNaN(Vector3d vector) { - return Double.isNaN(vector.x) || Double.isNaN(vector.y) - || Double.isNaN(vector.z); - } - - /** - * Returns true if the given vector is the zero vector, within a small - * margin of error (component-wise). - * - * @param vector - * The vector we are comparing to zero. - * @return True if the vector is approximately zero. - */ - public static boolean isZero(Vector3d vector) { - return Math.abs(vector.x) < EPSILON && Math.abs(vector.y) < EPSILON - && Math.abs(vector.z) < EPSILON; - } - -} diff --git a/gui/src/main/java/mesh/Ellipse.java b/gui/src/main/java/mesh/Ellipse.java deleted file mode 100644 index 2dda783..0000000 --- a/gui/src/main/java/mesh/Ellipse.java +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Copyright (c) 2018 Chiral Behaviors, LLC, all rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package mesh; - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.Vector3d; - -import com.hellblazer.delaunay.gui.PhiCoordinates; - -import javafx.geometry.Point3D; -import javafx.scene.paint.Material; -import javafx.scene.shape.Sphere; -import javafx.scene.transform.Rotate; -import javafx.scene.transform.Translate; -import mesh.polyhedra.plato.Octahedron; - -/** - * @author halhildebrand - * - */ -public class Ellipse { - private static double SQRT_3 = Math.sqrt(3); - private static final double TWO_PI = 2 * Math.PI; - - private final Point3D center; - private Point3D keyVertex; - private final Point3D u; - private final Point3D v; - - public Ellipse(int f, Octahedron oct, int vt) { - center = new Point3D(0, 0, 0); - - Face face = oct.getFaces().get(f); - Vector3d c = face.centroid(); - Vector3d vx = face.getVertices().get(vt); - - Point3D centroid = new Point3D(c.x, c.y, c.z); - Point3D vertex = new Point3D(vx.x, vx.y, vx.z); - - Point3D axis = new Point3D(centroid.getX(), centroid.getY(), centroid.getZ()); - - Rotate rotation = new Rotate(); - rotation.setPivotX(centroid.getX()); - rotation.setPivotY(centroid.getY()); - rotation.setPivotZ(centroid.getZ()); - rotation.setAxis(axis.normalize()); - - Translate translation = new Translate(); - translation.setX(-axis.getX()); - translation.setY(-axis.getY()); - translation.setZ(-axis.getZ()); - - if (PhiCoordinates.JITTERBUG_INVERSES[f]) { - rotation.setAngle(60); - } else { - rotation.setAngle(-60); - } - vertex = rotation.transform(vertex); - vertex = translation.transform(vertex); - keyVertex = vertex; - - double Z = (oct.getEdgeLength() * Math.sqrt(2)) / SQRT_3; - Point3D translate = axis.normalize().multiply(Z * Math.cos(0)); - translation.setX(translate.getX()); - translation.setY(translate.getY()); - translation.setZ(translate.getZ()); - rotation.setAngle(0); - vertex = rotation.transform(vertex); - vertex = translation.transform(vertex); - - u = vertex.subtract(center); - v = vertex.subtract(centroid).crossProduct(centroid).normalize().multiply(oct.getEdgeLength() / SQRT_3); - } - - public Ellipse(Point3D center, Point3D a, Point3D b) { - u = a.subtract(center); - v = b.subtract(center); - this.center = center; - } - - public PolyLine construct(int segments, Material material, double radius) { - List points = new ArrayList<>(); - double increment = TWO_PI / segments; - double theta = 0; - for (int i = 0; i <= segments; i++) { - points.add(u.multiply(Math.sin(theta)).add(v.multiply(Math.cos(theta)))); - theta += increment; - } - return new PolyLine(points, radius, material); - } - - public Point3D getCenter() { - return center; - } - - public Sphere getKeyVertexSphere() { - Sphere sphere = new Sphere(); - sphere.setRadius(1); - sphere.setTranslateX(keyVertex.getX()); - sphere.setTranslateY(keyVertex.getY()); - sphere.setTranslateZ(keyVertex.getZ()); - return sphere; - } - - public Point3D getU() { - return u; - } - - public Point3D getV() { - return v; - } -} diff --git a/gui/src/main/java/mesh/polyhedra/Antiprism.java b/gui/src/main/java/mesh/polyhedra/Antiprism.java deleted file mode 100644 index 62f01f3..0000000 --- a/gui/src/main/java/mesh/polyhedra/Antiprism.java +++ /dev/null @@ -1,81 +0,0 @@ -package mesh.polyhedra; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * A class for generating right antiprism meshes. - * - * @author Brian Yao - */ -public class Antiprism extends Polyhedron { - - private static double HEIGHT = 1.0; - private static double RADIUS = 0.5; - - /** - * Constructs an antiprism with a default radius (0.5) and default height - * (1.0). The number of sides of the base is the only parameter. - * - * @param numSides - * The number of sides the base has. - */ - public Antiprism(int numSides) { - this(numSides, RADIUS, HEIGHT); - } - - /** - * Constructs an antiprism whose base has the given circumradius and has the - * given height. The base is a regular n-gon, where n is given as a - * parameter. With high enough n, the geometry is an approximate cylinder. - * - * @param numSides - * The number of sides the base has. - * @param radius - * The circumradius of the base. - * @param height - * The height of the antiprism. - */ - public Antiprism(int numSides, double radius, double height) { - double centralAngle = 2.0 * Math.PI / numSides; - - Face bottomFace = new Face(numSides); - Face topFace = new Face(numSides); - int vertexIndex = 0; - for (int i = 0; i < numSides; i++) { - double totalAngleBottom = centralAngle * i; - double xb = radius * Math.cos(totalAngleBottom); - double yb = radius * Math.sin(totalAngleBottom); - Vector3d bottomVertex = new Vector3d(xb, yb, -height / 2.0); - - double totalAngleTop = totalAngleBottom + 0.5 * centralAngle; - double xt = radius * Math.cos(totalAngleTop); - double yt = radius * Math.sin(totalAngleTop); - Vector3d topVertex = new Vector3d(xt, yt, height / 2.0); - - addVertexPositions(bottomVertex, topVertex); - - bottomFace.setVertexIndex(numSides - i - 1, vertexIndex); - topFace.setVertexIndex(i, vertexIndex + 1); - - Face bottomTriangle = new Face(3); - Face topTriangle = new Face(3); - int nextBottom = (vertexIndex + 2) % (2 * numSides); - int nextTop = nextBottom + 1; - bottomTriangle.setAllVertexIndices(vertexIndex, nextBottom, - vertexIndex + 1); - topTriangle.setAllVertexIndices(vertexIndex + 1, nextBottom, - nextTop); - - addFaces(bottomTriangle, topTriangle); - - vertexIndex += 2; - } - - addFaces(bottomFace, topFace); - - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/Polyhedron.java b/gui/src/main/java/mesh/polyhedra/Polyhedron.java deleted file mode 100644 index 468a71c..0000000 --- a/gui/src/main/java/mesh/polyhedra/Polyhedron.java +++ /dev/null @@ -1,1272 +0,0 @@ -package mesh.polyhedra; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.vecmath.Vector3d; - -import math.VectorMath; -import mesh.Edge; -import mesh.Face; -import mesh.Mesh; -import mesh.struct.EdgeToAdjacentFace; -import mesh.struct.OrderedVertexToAdjacentEdge; -import mesh.struct.OrderedVertexToAdjacentFace; -import util.Canonicalize; -import util.PolyhedraUtils; - -/** - * A class for generic closed polyhedra meshes. The class contains several - * operations for creating new polyhedra from existing ones. The operation names - * and behaviors are based on Conway's polyhedron notation. Each such operation - * creates an entirely new mesh (the original remains unchanged by the - * operations). - * - * These operations rely heavily on the convention that faces' vertices are all - * specified in counter-clockwise order. - * - * @author Brian Yao - */ -public class Polyhedron extends Mesh { - - /** - * Create an empty polyhedron. - */ - public Polyhedron() { - super(); - } - - /** - * Copy constructor. - * - * @param polyhedron - * The polyhedron to copy. - */ - public Polyhedron(Polyhedron polyhedron) { - super(); - for (Vector3d vertexPos : vertexPositions) { - addVertexPosition(new Vector3d(vertexPos)); - } - for (Vector3d normal : vertexNormals) { - addVertexNormal(new Vector3d(normal)); - } - for (Face face : faces) { - addFace(new Face(face)); - } - } - - /** - * Computes the rectification of this polyhedron. This involves creating new - * vertices at the midpoints of the edges of the original polyhedron, and - * discarding the vertices of the original (they become faces). "Ambo" - * refers to the name of the operation under Conway's notation. - * - * @return The ambo polyhedron. - */ - public Polyhedron ambo() { - Polyhedron amboPolyhedron = new Polyhedron(); - - // Create new vertices, one at the midpoint of each edge - Map newVertices = new HashMap<>(); - int vertexIndex = 0; - for (Face face : faces) { - // Create a new face for each face on this polyhedron - Face newFace = new Face(face.numVertices()); - Edge[] edges = face.getEdges(); - for (int i = 0; i < face.numVertices(); i++) { - Edge edge = edges[i]; - if (newVertices.get(edge) == null) { - Vector3d edgeMidpt = edge.midpoint(); - amboPolyhedron.addVertexPosition(edgeMidpt); - newVertices.put(edge, vertexIndex++); - } - newFace.setVertexIndex(i, newVertices.get(edge)); - } - amboPolyhedron.addFace(newFace); - } - - // Construct new faces in place of vertices of original - OrderedVertexToAdjacentEdge ovtae = new OrderedVertexToAdjacentEdge(this); - for (int i = 0; i < numVertexPositions(); i++) { - List adjacentEdges = ovtae.getAdjacentEdges(i); - Face newVertexFace = new Face(adjacentEdges.size()); - for (int j = 0; j < adjacentEdges.size(); j++) { - newVertexFace.setVertexIndex(j, - newVertices.get(adjacentEdges.get(j))); - } - amboPolyhedron.addFace(newVertexFace); - } - - amboPolyhedron.setVertexNormalsToFaceNormals(); - return amboPolyhedron; - } - - /** - * Computes the "bevel" polyhedron of this polyhedron. Behaves similarly to - * expand in that there is one new face for each vertex and edge. Also known - * as cantitruncation. - * - * @return The bevel polyhedron. - */ - public Polyhedron bevel() { - return this.ambo() - .truncate(); - } - - /** - * Canonicalizes this polyhedron until the change in position does not - * exceed the given threshold. That is, the algorithm terminates when no - * vertex moves more than the threshold after one iteration. - * - * @param thresholdAdjust - * The threshold for change in one "adjust" iteration. - * @param thresholdPlanarize - * The threshold for change in one "planarize" iteration. - * @return The canonicalized version of this polyhedron. - */ - public Polyhedron canonicalize(double thresholdAdjust, - double thresholdPlanarize) { - Polyhedron canonicalized = this.clone(); - Canonicalize.adjust(canonicalized, thresholdAdjust); - Canonicalize.planarize(canonicalized, thresholdPlanarize); - return canonicalized; - } - - /** - * Canonicalizes this polyhedron for the given number of iterations. See - * util.Canonicalize for more details. Performs "adjust" followed by - * "planarize". - * - * @param iterationsAdjust - * The number of iterations to "adjust" for. - * @param iterationsPlanarize - * The number of iterations to "planarize" for. - * @return The canonicalized version of this polyhedron. - */ - public Polyhedron canonicalize(int iterationsAdjust, - int iterationsPlanarize) { - Polyhedron canonicalized = this.clone(); - Canonicalize.adjust(canonicalized, iterationsAdjust); - Canonicalize.planarize(canonicalized, iterationsPlanarize); - return canonicalized; - } - - /** - * Computes the "chamfer" polyhedron of this polyhedron. Truncates edges and - * replaces them with hexagonal faces. - * - * @return The chamfer polyhedron. - */ - public Polyhedron chamfer() { - return this.dual() - .subdivide() - .dual(); - } - - /** - * Clones a polyhedron. Equivalent to the copy constructor. Modifications - * made to the clone are separate from those made to the original. - * - * @return A clone of this polyhedron. - */ - @Override - public Polyhedron clone() { - Polyhedron clone = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - clone.addVertexPosition(new Vector3d(vertexPos)); - } - for (Vector3d normal : vertexNormals) { - clone.addVertexNormal(new Vector3d(normal)); - } - for (Face face : faces) { - clone.addFace(new Face(face)); - } - return clone; - } - - /** - * Computes the dual polyhedron of this polyhedron. The dual polyhedron has - * the "opposite" topology, in that it has one vertex for each face of the - * original polyhedron, and one face for each vertex of the original - * polyhedron. - * - * @return The dual polyhedron. - */ - public Polyhedron dual() { - Polyhedron dualPolyhedron = new Polyhedron(); - - // Create new vertices, one at the centroid of each face - Map newVertices = new HashMap<>(); - int vertexIndex = 0; - for (Face face : faces) { - Vector3d cent = face.vertexAverage(); - cent.scale(1.0 / cent.lengthSquared()); // Necessary for faces to be planar - dualPolyhedron.addVertexPosition(cent); - newVertices.put(face, vertexIndex++); - } - - // Construct new faces - OrderedVertexToAdjacentFace ovtaf = new OrderedVertexToAdjacentFace(this); - for (int i = 0; i < numVertexPositions(); i++) { - if (ovtaf.getAdjacentFaces(i) != null) { - List adjacentFaces = ovtaf.getAdjacentFaces(i); - Face newFace = new Face(adjacentFaces.size()); - for (int j = 0; j < adjacentFaces.size(); j++) { - Face jthFace = adjacentFaces.get(j); - int newVertexIndex = newVertices.get(jthFace); - newFace.setVertexIndex(j, newVertexIndex); - } - dualPolyhedron.addFace(newFace); - } - } - - dualPolyhedron.setVertexNormalsToFaceNormals(); - return dualPolyhedron; - } - - /** - * Computes the "edge-medial" polyhedron of this polyhedron. Places a vertex - * at the centroid of every face, and subdivides each edge into n segments, - * with edges from these subdivision points to the centroid. - * - * For example, the "edge-medial-3" operator corresponds to n = 3. - * - * @param n - * The number of subdivisions on each edge. - * @return The edge-medial polyhedron with n subdivisions per edge. - */ - public Polyhedron edgeMedial(int n) { - return medial(n, true); - } - - /** - * Computes the "exalt" polyhedron of this polyhedron. Equivalent to - * applying needle twice. - * - * @return The exalt polyhedron. - */ - public Polyhedron exalt() { - return this.needle() - .needle(); - } - - /** - * Computes the expanded polyhedron of this polyhedron. Each vertex becomes - * a face, and each edge becomes a quadrilateral face. The appearance of the - * returned polyhedron looks as if the original polyhedron's faces had been - * "pulled apart", and additional faces filled the gaps. - * - * @return The expanded polyhedron. - */ - public Polyhedron expand() { - return this.ambo() - .ambo(); - } - - /** - * Computes the "gyro" polyhedron of this polyhedron. Each face is divided - * into n pentagonal faces, where n is the number of vertices in the face. - * - * @return The gyro polyhedron. - */ - public Polyhedron gyro() { - Polyhedron gyroPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - gyroPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices on edges - Map> newVertices = PolyhedraUtils.subdivideEdges(this, - gyroPolyhedron, - 3); - - // Generate one vertex per face - Map centroidIndices = new HashMap<>(); - for (Face face : faces) { - // The centroid of each face becomes a vertex - Vector3d centroid = face.centroid(); - int centroidIndex = gyroPolyhedron.vertexPositions.size(); - gyroPolyhedron.addVertexPosition(centroid); - centroidIndices.put(face, centroidIndex); - } - - // Construct pentagonal faces - for (Face face : faces) { - Edge[] faceEdges = face.getEdges(); - - int[] prevEnds = faceEdges[faceEdges.length - 1].getEnds(); - int[] prevIndices = newVertices.get(prevEnds[0]) - .get(prevEnds[1]); - for (Edge faceEdge : faceEdges) { - int[] ends = faceEdge.getEnds(); - int[] edgeIndices = newVertices.get(ends[0]) - .get(ends[1]); - - Face pentagon = new Face(5); - pentagon.setAllVertexIndices(centroidIndices.get(face), - prevIndices[1], - faceEdge.getEnds()[0], - edgeIndices[0], edgeIndices[1]); - gyroPolyhedron.addFace(pentagon); - - // Update previous indices for next iteration - prevIndices = edgeIndices; - } - } - - gyroPolyhedron.setVertexNormalsToFaceNormals(); - return gyroPolyhedron; - } - - /** - * Computes the "join" polyhedron of this polyhedron. Each face of the - * original polyhedron becomes a raised pyramid, such that for two adjacent - * pyramids, the faces of the pyramids which share an edge are coplanar. In - * this way, we obtain a polyhedron made entirely of quadrilateral faces. - * - * @return The join polyhedron. - */ - public Polyhedron join() { - return this.ambo() - .dual(); - } - - /** - * Computes the "joined-lace" polyhedron of this polyhedron. Like lace, but - * old edges are replaced by quadrilateral faces instead of two triangular - * faces. - * - * @return The joined-lace polyhedron. - */ - public Polyhedron joinedLace() { - return this.lace(-1, true, true); - } - - /** - * Computes the "joined-medial" polyhedron of this polyhedron. The same as - * medial, but with rhombic faces im place of original edges. - * - * @return The joined-medial polyhedron. - */ - public Polyhedron joinedMedial() { - Polyhedron medialPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - medialPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Generate new vertices and rhombic faces on original edges - Map> edgeToVertex = PolyhedraUtils.addEdgeToCentroidVertices(this, - medialPolyhedron); - PolyhedraUtils.addRhombicFacesAtEdges(this, medialPolyhedron, - edgeToVertex); - - // Generate triangular faces - int vertexIndex = medialPolyhedron.numVertexPositions(); - for (Face face : faces) { - Vector3d centroid = face.centroid(); - medialPolyhedron.addVertexPosition(centroid); - - Edge[] edges = face.getEdges(); - int[] prevEnds = edges[edges.length - 1].getEnds(); - int prevVertex = edgeToVertex.get(prevEnds[0]) - .get(prevEnds[1]); - for (Edge edge : edges) { - int[] ends = edge.getEnds(); - int currVertex = edgeToVertex.get(ends[0]) - .get(ends[1]); - - Face triangle1 = new Face(3); - Face triangle2 = new Face(3); - triangle1.setAllVertexIndices(vertexIndex, ends[0], currVertex); - triangle2.setAllVertexIndices(vertexIndex, prevVertex, ends[0]); - - medialPolyhedron.addFaces(triangle1, triangle2); - - prevVertex = currVertex; - } - - vertexIndex++; - } - - medialPolyhedron.setVertexNormalsToFaceNormals(); - return medialPolyhedron; - } - - /** - * Computes the "kis" polyhedron of this polyhedron. Each face of the - * original polyhedron becomes a raised pyramid; the returned polyhedron is - * not necessarily convex. - * - * @return The kis polyhedron - */ - public Polyhedron kis() { - return this.dual() - .needle(); - } - - /** - * Same as kis, but only divides faces with exactly n sides. All other faces - * in the original polyhedron are preserved. - * - * @param n - * The number of sides on the faces we want to kis. - * @return The polyhedron with kis applied to faces with n sides. - */ - public Polyhedron kis(int n) { - Polyhedron kisPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - kisPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - int vertexIndex = kisPolyhedron.numVertexPositions(); - for (Face face : faces) { - if (face.numVertices() == n) { - // Only kis if the face has the desired number of sides - Vector3d centroid = face.centroid(); - kisPolyhedron.addVertexPosition(centroid); - - int prevVertIndex = face.getVertexIndex(face.numVertices() - 1); - for (int faceVertIndex : face.getVertexIndices()) { - Face triangle = new Face(3); - triangle.setAllVertexIndices(vertexIndex, prevVertIndex, - faceVertIndex); - kisPolyhedron.addFace(triangle); - - prevVertIndex = faceVertIndex; - } - - vertexIndex++; - } else { - // Otherwise, use original face - kisPolyhedron.addFace(new Face(face)); - } - } - - kisPolyhedron.setVertexNormalsToFaceNormals(); - return kisPolyhedron; - } - - /** - * Computes the "lace" polyhedron of this polyhedron. Like loft, but has on - * each face an antiprism of the original face instead of a prism. - * - * @return The lace polyhedron. - */ - public Polyhedron lace() { - return this.lace(-1, true, false); - } - - /** - * Computes the "lace" polyhedron of this polyhedron, except the operation - * is only applied to faces with the specified number of sides. - * - * @param n - * The number of sides a face needs to have lace applied to it. - * @return The polyhedron with lace applied to faces with n sides. - */ - public Polyhedron lace(int n) { - return this.lace(n, false, false); - } - - /** - * Computes the "loft" polyhedron of this polyhedron. Adds a smaller version - * of this face, with n trapezoidal faces connecting the inner smaller - * version and the outer original version, where n is the number of vertices - * the face has. - * - * @return The loft polyhedron. - */ - public Polyhedron loft() { - return this.loft(-1, true); - } - - /** - * Computes the "loft" polyhedron of this polyhedron, except only faces with - * the specified number of sides are lofted. - * - * @param n - * The number of sides a face needs to have loft applied to it. - * @return The polyhedron with loft applied to faces with n sides. - */ - public Polyhedron loft(int n) { - return this.loft(n, false); - } - - /** - * Computes the "medial" polyhedron of this polyhedron. Adds vertices at the - * face centroids and edge midpoints. Each face is split into 2n triangles, - * where n is the number of vertices in the face. These triangles share a - * vertex at the face's centroid. - * - * @return The medial polyhedron. - */ - public Polyhedron medial() { - return this.medial(2); - } - - /** - * Generalized medial, parametrized on the number of subdivisions on each - * edge. The regular medial operation corresponds to n = 2 subdivisions. - * - * @param n - * The number of subdivisions on each edge. - * @return The medial polyhedron with n subdivisions per edge. - */ - public Polyhedron medial(int n) { - return medial(n, false); - } - - /** - * Computes the "needle" polyhedron of this polyhedron. The centroid of each - * face becomes a vertex, and for each edge, there are two triangular faces - * which cross the original edge; the edge shared by these two triangular - * faces goes between the centroids of the two original faces. The returned - * polyhedron is not necessarily convex. - * - * @return The needle polyhedron. - */ - public Polyhedron needle() { - Polyhedron needlePolyhedron = new Polyhedron(); - needlePolyhedron.addVertexPositions(vertexPositions); - - // Construct new vertices, one at the centroid of each face - Map newVertices = new HashMap<>(); - int vertexIndex = vertexPositions.size(); - for (Face face : faces) { - Vector3d cent = face.centroid(); - needlePolyhedron.addVertexPosition(cent); - newVertices.put(face, vertexIndex++); - } - - // Construct new faces, two per edge - EdgeToAdjacentFace etaf = new EdgeToAdjacentFace(this); - for (Edge edge : etaf.getEdges()) { - int[] edgeEnds = edge.getEnds(); - Face[] adjacentFaces = etaf.getAdjacentFaces(edge); - - // Check orientation: make sure faces we make are specified in - // CCW order - for (int i = 0; i < adjacentFaces[0].numVertices(); i++) { - int v = adjacentFaces[0].getVertexIndex(i); - if (v == edgeEnds[0]) { - int vnext = (i + 1) % adjacentFaces[0].numVertices(); - if (adjacentFaces[0].getVertexIndex(vnext) != edgeEnds[1]) { - // Swap order of adjacent faces - Face temp = adjacentFaces[0]; - adjacentFaces[0] = adjacentFaces[1]; - adjacentFaces[1] = temp; - } - break; - } - } - - Face topFace = new Face(3); - Face bottomFace = new Face(3); - int vface0 = newVertices.get(adjacentFaces[0]); - int vface1 = newVertices.get(adjacentFaces[1]); - topFace.setAllVertexIndices(vface0, vface1, edgeEnds[1]); - bottomFace.setAllVertexIndices(vface1, vface0, edgeEnds[0]); - needlePolyhedron.addFaces(topFace, bottomFace); - } - - needlePolyhedron.setVertexNormalsToFaceNormals(); - return needlePolyhedron; - } - - /** - * Computes the "ortho" polyhedron of this polyhedron. Each face is divided - * into n quadrilateral faces, where n is the number of vertices in the - * face. - * - * @return The ortho polyhedron. - */ - public Polyhedron ortho() { - return this.expand() - .dual(); - } - - /** - * Computes the "propellor" polyhedron of this polyhedron. It is like gyro, - * but instead of having a central vertex we have a central face. This - * creates quadrilateral faces instead of pentagonal faces. - * - * @return The propellor polyhedron. - */ - public Polyhedron propellor() { - Polyhedron propellorPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - propellorPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices on edges - Map> newVertices = PolyhedraUtils.subdivideEdges(this, - propellorPolyhedron, - 3); - - // Create quadrilateral faces and one central face on each face - for (Face face : faces) { - Edge[] faceEdges = face.getEdges(); - - Face centralFace = new Face(face.numVertices()); - int[] prevEnds = faceEdges[faceEdges.length - 1].getEnds(); - int[] prevEdgeVertices = newVertices.get(prevEnds[0]) - .get(prevEnds[1]); - for (int i = 0; i < faceEdges.length; i++) { - int[] ends = faceEdges[i].getEnds(); - int[] newEdgeVertices = newVertices.get(ends[0]) - .get(ends[1]); - - Face quad = new Face(4); - quad.setAllVertexIndices(ends[0], newEdgeVertices[0], - prevEdgeVertices[0], - prevEdgeVertices[1]); - propellorPolyhedron.addFace(quad); - - centralFace.setVertexIndex(i, newEdgeVertices[0]); - - prevEnds = ends; - prevEdgeVertices = newEdgeVertices; - } - - propellorPolyhedron.addFace(centralFace); - } - - propellorPolyhedron.setVertexNormalsToFaceNormals(); - return propellorPolyhedron; - } - - /** - * Compute the "quinto" polyhedron of this polyhedron. Equivalent to an - * ortho but truncating the vertex at the center of original faces. This - * creates a small copy of the original face (but rotated). - * - * @return The quinto polyhedron. - */ - public Polyhedron quinto() { - Polyhedron quintoPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - quintoPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices at the midpoint of each edge and toward the - // face's centroid - Map> edgeToVertex = PolyhedraUtils.addEdgeToCentroidVertices(this, - quintoPolyhedron); - - int vertexIndex = quintoPolyhedron.numVertexPositions(); - Map midptVertices = new HashMap<>(); - for (Edge edge : this.getEdges()) { - quintoPolyhedron.addVertexPosition(edge.midpoint()); - midptVertices.put(edge, vertexIndex++); - } - - // Generate new faces - for (Face face : faces) { - Face centralFace = new Face(face.numVertices()); - Edge[] edges = face.getEdges(); - - int[] prevEnds = edges[edges.length - 1].getEnds(); - int prevVertex = edgeToVertex.get(prevEnds[0]) - .get(prevEnds[1]); - int prevMidpt = midptVertices.get(edges[edges.length - 1]); - int centralIndex = 0; - for (Edge currEdge : edges) { - int[] currEnds = currEdge.getEnds(); - int currVertex = edgeToVertex.get(currEnds[0]) - .get(currEnds[1]); - int currMidpt = midptVertices.get(currEdge); - - Face pentagon = new Face(5); - pentagon.setAllVertexIndices(prevVertex, prevMidpt, currEnds[0], - currMidpt, currVertex); - quintoPolyhedron.addFace(pentagon); - - centralFace.setVertexIndex(centralIndex++, currVertex); - - // Update previous vertex indices - prevVertex = currVertex; - prevMidpt = currMidpt; - } - quintoPolyhedron.addFace(centralFace); - } - - quintoPolyhedron.setVertexNormalsToFaceNormals(); - return quintoPolyhedron; - } - - /** - * Computes the "snub" polyhedron of this polyhedron. Essentially, each face - * is twisted, and each edge is replaced with two equilateral triangles. - * Each vertex also becomes a new face. - * - * @return The snub polyhedron. - */ - public Polyhedron snub() { - return this.gyro() - .dual(); - } - - /** - * Computes the "stake" polyhedron of this polyhedron. Like lace, but - * instead of having a central face, there is a central vertex and - * quadrilaterals around the center. - * - * @return The stake polyhedron. - */ - public Polyhedron stake() { - return this.stake(-1, true); - } - - /** - * Computes the "stake" polyhedron of this polyhedron, but only performs the - * operation on faces with n sides. - * - * @param n - * The number of sides a face needs to have stake applied to it. - * @return The polyhedron with stake applied to faces with n sides. - */ - public Polyhedron stake(int n) { - return this.stake(n, false); - } - - /** - * Computes the "subdivide" polyhedron of this polyhedron. Adds vertices at - * the midpoints of edges, and creates new triangular faces around original - * vertices. Equivalent to ambo without removing the original vertices. - * - * @return The subdivide polyhedron. - */ - public Polyhedron subdivide() { - Polyhedron subdividePolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - subdividePolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices, one at the midpoint of each edge - Map newVertices = new HashMap<>(); - int vertexIndex = subdividePolyhedron.numVertexPositions(); - for (Face face : faces) { - // Create a new face for each face on this polyhedron - Face newFace = new Face(face.numVertices()); - Edge[] edges = face.getEdges(); - for (int i = 0; i < face.numVertices(); i++) { - Edge edge = edges[i]; - if (newVertices.get(edge) == null) { - Vector3d edgeMidpt = edge.midpoint(); - subdividePolyhedron.addVertexPosition(edgeMidpt); - newVertices.put(edge, vertexIndex++); - } - newFace.setVertexIndex(i, newVertices.get(edge)); - } - subdividePolyhedron.addFace(newFace); - } - - // Create new faces for each vertex - OrderedVertexToAdjacentEdge ovtae = new OrderedVertexToAdjacentEdge(this); - for (int i = 0; i < this.numVertexPositions(); i++) { - List adjacentEdges = ovtae.getAdjacentEdges(i); - - Edge prevEdge = adjacentEdges.get(adjacentEdges.size() - 1); - for (Edge edge : adjacentEdges) { - int prevVertex = newVertices.get(prevEdge); - int currVertex = newVertices.get(edge); - Face triangle = new Face(3); - triangle.setAllVertexIndices(i, prevVertex, currVertex); - - subdividePolyhedron.addFace(triangle); - - // Update previous edge - prevEdge = edge; - } - } - - subdividePolyhedron.setVertexNormalsToFaceNormals(); - return subdividePolyhedron; - } - - /** - * Computes the truncated polyhedron of this polyhedron. Each vertex is - * truncated, leaving behind a polygon face instead. - * - * @return The truncated polyhedron. - */ - public Polyhedron truncate() { - return this.needle() - .dual(); - } - - /** - * Same as truncate, but only truncates vertices with exactly n incident - * faces. All other vertices in the original polyhedron are preserved. - * - * @param n - * The order of vertices to truncate. - * @return The polyhedron with order n vertices truncated. - */ - public Polyhedron truncate(int n) { - Polyhedron truncatePolyhedron = new Polyhedron(); - - // Compute new vertices - Map> edgeVertices = new HashMap<>(); - Map oldToNewIndices = new HashMap<>(); - OrderedVertexToAdjacentEdge ov2ae = new OrderedVertexToAdjacentEdge(this); - int vertexIndex = 0; - for (int i = 0; i < vertexPositions.size(); i++) { - List adjEdges = ov2ae.getAdjacentEdges(i); - if (adjEdges.size() == n) { - // Only truncate if the vertex has the desired order - Face truncateFace = new Face(n); - int faceVertexIndex = 0; - Vector3d vertPos = vertexPositions.get(i); - for (Edge edge : adjEdges) { - Vector3d otherPos = edge.getOtherLocation(i); - Vector3d newVert = VectorMath.interpolate(vertPos, otherPos, - 0.3); // 0 < arbitrary scale factor < 0.5 - - truncatePolyhedron.addVertexPosition(newVert); - edgeVertices.computeIfAbsent(i, - a -> new HashMap()); - edgeVertices.get(i) - .put(edge.getOtherEnd(i), vertexIndex); - truncateFace.setVertexIndex(faceVertexIndex++, vertexIndex); - vertexIndex++; - } - - truncatePolyhedron.addFace(truncateFace); - } else if (!oldToNewIndices.containsKey(i)) { - // Keep old vertex; only add it once - truncatePolyhedron.addVertexPosition(vertexPositions.get(i)); - oldToNewIndices.put(i, vertexIndex++); - } - } - - for (Face face : faces) { - List newFaceVertices = new ArrayList<>(); - int prevIndex = face.getVertexIndex(face.numVertices() - 1); - for (int j = 0; j < face.numVertices(); j++) { - int currIndex = face.getVertexIndex(j); - if (edgeVertices.containsKey(currIndex)) { - // If the vertex was truncated, use two new vertices - int nextIndex = face.getVertexIndex((j + 1) - % face.numVertices()); - newFaceVertices.add(edgeVertices.get(currIndex) - .get(prevIndex)); - newFaceVertices.add(edgeVertices.get(currIndex) - .get(nextIndex)); - } else { - // Otherwise, just use old vertex - newFaceVertices.add(oldToNewIndices.get(currIndex)); - } - - // Update previous index - prevIndex = currIndex; - } - - Face newFace = new Face(newFaceVertices.size()); - for (int k = 0; k < newFaceVertices.size(); k++) { - newFace.setVertexIndex(k, newFaceVertices.get(k)); - } - truncatePolyhedron.addFace(newFace); - } - - truncatePolyhedron.setVertexNormalsToFaceNormals(); - return truncatePolyhedron; - } - - /** - * Computes the "volute" polyhedron of this polyhedron. Equivalent to a snub - * operation followed by kis on the original faces. This is the dual of - * whirl. - * - * @return The volute polyhedron. - */ - public Polyhedron volute() { - return this.whirl() - .dual(); - } - - /** - * Computes the "whirl" polyhedron of this polyhedron. Forms hexagon faces - * at each edge, with a small copy of the original face at the center of the - * original face. - * - * @return The whirl polyhedron. - */ - public Polyhedron whirl() { - Polyhedron whirlPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - whirlPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices on edges - Map> newVertices = PolyhedraUtils.subdivideEdges(this, - whirlPolyhedron, - 3); - - // Generate vertices near the center of each face - Map centerVertices = new HashMap<>(); - int vertexIndex = whirlPolyhedron.vertexPositions.size(); - for (Face face : faces) { - int[] newCenterIndices = new int[face.numVertices()]; - Vector3d centroid = face.centroid(); - int i = 0; - for (Edge edge : face.getEdges()) { - int[] ends = edge.getEnds(); - int[] edgeVertices = newVertices.get(ends[0]) - .get(ends[1]); - Vector3d edgePoint = whirlPolyhedron.vertexPositions.get(edgeVertices[1]); - Vector3d diff = new Vector3d(); - diff.sub(edgePoint, centroid); - diff.scale(0.3); // 0 < arbitrary scale factor < 1 - - Vector3d newFacePoint = new Vector3d(); - newFacePoint.add(centroid, diff); - - whirlPolyhedron.addVertexPosition(newFacePoint); - newCenterIndices[i++] = vertexIndex++; - } - - centerVertices.put(face, newCenterIndices); - } - - // Generate hexagonal faces and central face - for (Face face : faces) { - Face centralFace = new Face(face.numVertices()); - - Edge[] faceEdges = face.getEdges(); - int[] centralVertices = centerVertices.get(face); - int[] pEnds = faceEdges[faceEdges.length - 1].getEnds(); - int[] prevEdgeVertices = newVertices.get(pEnds[0]) - .get(pEnds[1]); - int prevCenterIndex = centralVertices[centralVertices.length - 1]; - for (int i = 0; i < face.numVertices(); i++) { - int[] ends = faceEdges[i].getEnds(); - int[] edgeVertices = newVertices.get(ends[0]) - .get(ends[1]); - int currCenterIndex = centralVertices[i]; - - Face hexagon = new Face(6); - hexagon.setAllVertexIndices(ends[0], edgeVertices[0], - edgeVertices[1], currCenterIndex, - prevCenterIndex, - prevEdgeVertices[1]); - whirlPolyhedron.addFace(hexagon); - - centralFace.setVertexIndex(i, currCenterIndex); - - prevEdgeVertices = edgeVertices; - prevCenterIndex = currCenterIndex; - } - - whirlPolyhedron.addFace(centralFace); - } - - whirlPolyhedron.setVertexNormalsToFaceNormals(); - return whirlPolyhedron; - } - - /** - * Computes the "yank" polyhedron of this polyhedron. Equivalent to applying - * zip twice. - * - * @return The yank polyhedron. - */ - public Polyhedron yank() { - return this.zip() - .zip(); - } - - /** - * Computes the "zip" polyhedron of this polyhedron. Also known as a - * bitruncation operation, this is equivalent to the truncation of the dual - * polyhedron and the dual of kis. - * - * @return The zip polyhedron. - */ - public Polyhedron zip() { - return this.kis() - .dual(); - } - - /** - * A helper method for implementing lace, parametrized lace, and - * joined-lace. - * - * @param n - * The number of sides a face needs to have lace applied to it. - * @param ignore - * True if we want to ignore the parameter n. - * @param joined - * True if we want to compute joined-lace. - * @return The lace polyhedron. - */ - private Polyhedron lace(int n, boolean ignore, boolean joined) { - Polyhedron lacePolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - lacePolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Generate new vertices - Map> edgeToVertex = PolyhedraUtils.addEdgeToCentroidVertices(this, - lacePolyhedron); - - if (joined) { - PolyhedraUtils.addRhombicFacesAtEdges(this, lacePolyhedron, - edgeToVertex); - } - - // Generate new faces - for (Face face : faces) { - if (ignore || face.numVertices() == n) { - Face twist = new Face(face.numVertices()); - Edge[] edges = face.getEdges(); - - for (int i = 0; i < edges.length; i++) { - // Build face at center of each original face - int[] ends = edges[i].getEnds(); - int newVertex = edgeToVertex.get(ends[0]) - .get(ends[1]); - twist.setVertexIndex(i, newVertex); - - // Always generate triangles from vertices to central face - int nextInd = (i + 1) % edges.length; - int[] nextEnds = edges[nextInd].getEnds(); - int nextNewVertex = edgeToVertex.get(nextEnds[0]) - .get(nextEnds[1]); - - Face smallTriangle = new Face(3); - smallTriangle.setAllVertexIndices(nextNewVertex, newVertex, - ends[1]); - - lacePolyhedron.addFace(smallTriangle); - } - - lacePolyhedron.addFace(twist); - - if (!joined) { - // If not joined, generate triangle faces - for (Edge edge : edges) { - int[] ends = edge.getEnds(); - int currVertex = edgeToVertex.get(ends[0]) - .get(ends[1]); - - Face largeTriangle = new Face(3); - largeTriangle.setAllVertexIndices(currVertex, ends[0], - ends[1]); - - lacePolyhedron.addFace(largeTriangle); - } - } - } else { - // Keep original face - lacePolyhedron.addFace(new Face(face)); - } - } - - lacePolyhedron.setVertexNormalsToFaceNormals(); - return lacePolyhedron; - } - - /** - * A helper method which implements the loft operation, both the version - * parametrized on the number of sides of affected faces and the one without - * the parameter. If the "ignore" flag is set to true, every face is - * modified. - * - * @param n - * The number of sides a face needs to have loft applied to it. - * @param ignore - * True if we want to ignore the parameter n. - * @return The loft polyhedron. - */ - private Polyhedron loft(int n, boolean ignore) { - Polyhedron loftPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - loftPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Generate new vertices - Map newVertices = new HashMap<>(); - int vertexIndex = loftPolyhedron.numVertexPositions(); - for (Face face : faces) { - if (ignore || face.numVertices() == n) { - Face shrunk = new Face(face.numVertices()); - int[] newFaceVertices = new int[face.numVertices()]; - - Vector3d centroid = face.centroid(); - for (int i = 0; i < face.numVertices(); i++) { - int index = face.getVertexIndex(i); - Vector3d vertex = vertexPositions.get(index); - Vector3d newVertex = VectorMath.interpolate(vertex, - centroid, 0.3); - - loftPolyhedron.addVertexPosition(newVertex); - newFaceVertices[i] = vertexIndex; - shrunk.setVertexIndex(i, vertexIndex); - vertexIndex++; - } - - newVertices.put(face, newFaceVertices); - loftPolyhedron.addFace(shrunk); - } - } - - // Generate new faces - for (Face face : faces) { - if (newVertices.containsKey(face)) { - int[] newFaceVertices = newVertices.get(face); - int prevIndex = face.getVertexIndex(face.numVertices() - 1); - int newPrevIndex = newFaceVertices[face.numVertices() - 1]; - for (int i = 0; i < face.numVertices(); i++) { - int currIndex = face.getVertexIndex(i); - int newCurrIndex = newFaceVertices[i]; - - Face trapezoid = new Face(4); - trapezoid.setAllVertexIndices(prevIndex, currIndex, - newCurrIndex, newPrevIndex); - loftPolyhedron.addFace(trapezoid); - - prevIndex = currIndex; - newPrevIndex = newCurrIndex; - } - } else { - // Keep original face - loftPolyhedron.addFace(new Face(face)); - } - } - - loftPolyhedron.setVertexNormalsToFaceNormals(); - return loftPolyhedron; - } - - /** - * A helper method for computing edge-medial and medial (parametrized). - * - * @param n - * The number of subdivisions per edge. - * @param edge - * True if computing edge-medial, false if regular medial. - * @return The medial polyhedron subjected to the input constraints. - */ - private Polyhedron medial(int n, boolean edge) { - Polyhedron medialPolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - medialPolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Create new vertices on edges - Map> newVertices = PolyhedraUtils.subdivideEdges(this, - medialPolyhedron, - n); - - int vertexIndex = medialPolyhedron.numVertexPositions(); - for (Face face : faces) { - Vector3d centroid = face.centroid(); - - Edge[] faceEdges = face.getEdges(); - - Edge prevEdge = faceEdges[faceEdges.length - 1]; - int[] prevEnds = prevEdge.getEnds(); - for (Edge currEdge : faceEdges) { - int[] currEnds = currEdge.getEnds(); - int[] currNewVerts = newVertices.get(currEnds[0]) - .get(currEnds[1]); - - int prevLastVert = newVertices.get(prevEnds[0]) - .get(prevEnds[1])[n - 2]; - if (edge) { - // One quadrilateral face - Face quad = new Face(4); - quad.setAllVertexIndices(currEnds[0], currNewVerts[0], - vertexIndex, prevLastVert); - - medialPolyhedron.addFace(quad); - } else { - // Two triangular faces - Face triangle1 = new Face(3); - Face triangle2 = new Face(3); - triangle1.setAllVertexIndices(currEnds[0], currNewVerts[0], - vertexIndex); - triangle2.setAllVertexIndices(vertexIndex, prevLastVert, - currEnds[0]); - - medialPolyhedron.addFaces(triangle1, triangle2); - } - - // Create new triangular faces at edges - for (int i = 0; i < currNewVerts.length - 1; i++) { - Face edgeTriangle = new Face(3); - edgeTriangle.setAllVertexIndices(vertexIndex, - currNewVerts[i], - currNewVerts[i + 1]); - - medialPolyhedron.addFace(edgeTriangle); - } - } - - medialPolyhedron.addVertexPosition(centroid); - vertexIndex++; - } - - medialPolyhedron.setVertexNormalsToFaceNormals(); - return medialPolyhedron; - } - - /** - * A helper method for implementing stake and parametrized stake. - * - * @param n - * The number of sides a face needs to have stake applied to it. - * @param ignore - * True if we want to ignore the parameter n. - * @return The stake polyhedron. - */ - private Polyhedron stake(int n, boolean ignore) { - Polyhedron stakePolyhedron = new Polyhedron(); - for (Vector3d vertexPos : vertexPositions) { - stakePolyhedron.addVertexPosition(new Vector3d(vertexPos)); - } - - // Generate new vertices - Map> edgeToVertex = PolyhedraUtils.addEdgeToCentroidVertices(this, - stakePolyhedron); - - int vertexIndex = stakePolyhedron.numVertexPositions(); - for (Face face : faces) { - if (ignore || face.numVertices() == n) { - Vector3d centroid = face.centroid(); - stakePolyhedron.addVertexPosition(centroid); - int centroidIndex = vertexIndex++; - - Edge[] edges = face.getEdges(); - - // Generate the quads and triangles on this face - for (int i = 0; i < edges.length; i++) { - int[] ends = edges[i].getEnds(); - int currVertex = edgeToVertex.get(ends[0]) - .get(ends[1]); - int[] nextEnds = edges[(i + 1) % edges.length].getEnds(); - int nextVertex = edgeToVertex.get(nextEnds[0]) - .get(nextEnds[1]); - - Face triangle = new Face(3); - Face quad = new Face(4); - triangle.setAllVertexIndices(currVertex, ends[0], ends[1]); - quad.setAllVertexIndices(nextVertex, centroidIndex, - currVertex, ends[1]); - - stakePolyhedron.addFaces(triangle, quad); - } - } else { - // Keep original face - stakePolyhedron.addFace(new Face(face)); - } - } - - stakePolyhedron.setVertexNormalsToFaceNormals(); - return stakePolyhedron; - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/Prism.java b/gui/src/main/java/mesh/polyhedra/Prism.java deleted file mode 100644 index 877db31..0000000 --- a/gui/src/main/java/mesh/polyhedra/Prism.java +++ /dev/null @@ -1,77 +0,0 @@ -package mesh.polyhedra; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * A class for generating right prism meshes. - * - * @author Brian Yao - */ -public class Prism extends Polyhedron { - - private static double HEIGHT = 1.0; - private static double RADIUS = 0.5; - - /** - * Constructs a prism with a default radius (0.5) and default height (1.0). - * The number of sides of the base is the only parameter. - * - * @param numSides - * The number of sides the base has. - */ - public Prism(int numSides) { - this(numSides, RADIUS, HEIGHT); - } - - /** - * Constructs a prism whose base has the given circumradius and has the - * given height. The base is a regular n-gon, where n is given as a - * parameter. With high enough n, the geometry is an approximate cylinder. - * - * @param numSides - * The number of sides the base has. - * @param radius - * The circumradius of the base. - * @param height - * The height of the prism. - */ - public Prism(int numSides, double radius, double height) { - Vector3d toTop = new Vector3d(0.0, 0.0, height); - double centralAngle = 2.0 * Math.PI / numSides; - - Face bottomFace = new Face(numSides); - Face topFace = new Face(numSides); - int vertexIndex = 0; - for (int i = 0; i < numSides; i++) { - double totalAngle = centralAngle * i; - double x = radius * Math.cos(totalAngle); - double y = radius * Math.sin(totalAngle); - Vector3d bottomVertex = new Vector3d(x, y, -height / 2.0); - - Vector3d topVertex = new Vector3d(); - topVertex.add(bottomVertex, toTop); - - addVertexPositions(bottomVertex, topVertex); - - bottomFace.setVertexIndex(numSides - i - 1, vertexIndex); - topFace.setVertexIndex(i, vertexIndex + 1); - - Face quad = new Face(4); - int nextBottom = (vertexIndex + 2) % (2 * numSides); - int nextTop = nextBottom + 1; - quad.setAllVertexIndices(vertexIndex, nextBottom, nextTop, - vertexIndex + 1); - - addFace(quad); - - vertexIndex += 2; - } - - addFaces(bottomFace, topFace); - - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/Pyramid.java b/gui/src/main/java/mesh/polyhedra/Pyramid.java deleted file mode 100644 index e61dcc9..0000000 --- a/gui/src/main/java/mesh/polyhedra/Pyramid.java +++ /dev/null @@ -1,68 +0,0 @@ -package mesh.polyhedra; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * A class for generating right pyramid meshes. - * - * @author Brian Yao - */ -public class Pyramid extends Polyhedron { - - private static double HEIGHT = 1.0; - private static double RADIUS = 0.5; - - /** - * Constructs a pyramid with a default radius (0.5) and default height - * (1.0). The number of sides of the base is the only parameter. - * - * @param numSides - * The number of sides the base has. - */ - public Pyramid(int numSides) { - this(numSides, RADIUS, HEIGHT); - } - - /** - * Constructs a pyramid whose base has the given circumradius and has the - * given height. The base is a regular n-gon, where n is given as a - * parameter. With high enough n, the geometry is an approximate cylinder. - * - * @param numSides - * The number of sides the base has. - * @param radius - * The circumradius of the base. - * @param height - * The height of the pyramid. - */ - public Pyramid(int numSides, double radius, double height) { - double centralAngle = 2.0 * Math.PI / numSides; - - Face bottomFace = new Face(numSides); - int vertexIndex = 0; - for (int i = 0; i < numSides; i++) { - double totalAngle = centralAngle * i; - double x = radius * Math.cos(totalAngle); - double y = radius * Math.sin(totalAngle); - Vector3d bottomVertex = new Vector3d(x, y, -height / 2.0); - - addVertexPosition(bottomVertex); - - bottomFace.setVertexIndex(numSides - i - 1, vertexIndex); - - Face triangle = new Face(3); - int nextVertex = (vertexIndex + 1) % numSides; - triangle.setAllVertexIndices(vertexIndex++, nextVertex, numSides); - - addFace(triangle); - } - - addVertexPosition(new Vector3d(0.0, 0.0, height / 2)); - addFace(bottomFace); - - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/archimedes/ArchimedeanSolid.java b/gui/src/main/java/mesh/polyhedra/archimedes/ArchimedeanSolid.java deleted file mode 100644 index 1d9cc12..0000000 --- a/gui/src/main/java/mesh/polyhedra/archimedes/ArchimedeanSolid.java +++ /dev/null @@ -1,12 +0,0 @@ -package mesh.polyhedra.archimedes; - -import mesh.polyhedra.Polyhedron; - -/** - * Abstract class for an Archimedean solid mesh centered at the origin. - * - * @author Brian Yao - */ -public abstract class ArchimedeanSolid extends Polyhedron { - -} diff --git a/gui/src/main/java/mesh/polyhedra/archimedes/Cuboctahedron.java b/gui/src/main/java/mesh/polyhedra/archimedes/Cuboctahedron.java deleted file mode 100644 index 5154dbf..0000000 --- a/gui/src/main/java/mesh/polyhedra/archimedes/Cuboctahedron.java +++ /dev/null @@ -1,29 +0,0 @@ -package mesh.polyhedra.archimedes; - -import mesh.polyhedra.Polyhedron; -import mesh.polyhedra.plato.Cube; - -/** - * An implementation of a regular cuboctahedron mesh. - * - * @author Brian Yao - */ -public class Cuboctahedron extends ArchimedeanSolid { - - /** - * Construct a cuboctahedron mesh centered at the origin with the specified - * edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Cuboctahedron(double edgeLength) { - Cube cube = new Cube(Math.sqrt(2.0) * edgeLength); - Polyhedron cubeAmbo = cube.ambo(); - addVertexPositions(cubeAmbo.getVertexPositions()); - addVertexNormals(cubeAmbo.getVertexNormals()); - addFaces(cubeAmbo.getFaces()); - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/archimedes/Icosidodecahedron.java b/gui/src/main/java/mesh/polyhedra/archimedes/Icosidodecahedron.java deleted file mode 100644 index eeea5fd..0000000 --- a/gui/src/main/java/mesh/polyhedra/archimedes/Icosidodecahedron.java +++ /dev/null @@ -1,31 +0,0 @@ -package mesh.polyhedra.archimedes; - -import mesh.polyhedra.Polyhedron; -import mesh.polyhedra.plato.Dodecahedron; - -/** - * An implementation of a regular icosidodecahedron mesh. - * - * @author Brian Yao - */ -public class Icosidodecahedron extends ArchimedeanSolid { - - private static final double SCALE_FACTOR = Math.sin(Math.toRadians(54)); - - /** - * Construct a icosidodecahedron mesh centered at the origin with the - * specified edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Icosidodecahedron(double edgeLength) { - Dodecahedron dodec = new Dodecahedron(edgeLength / SCALE_FACTOR); - Polyhedron dodecAmbo = dodec.ambo(); - addVertexPositions(dodecAmbo.getVertexPositions()); - addVertexNormals(dodecAmbo.getVertexNormals()); - addFaces(dodecAmbo.getFaces()); - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/Cube.java b/gui/src/main/java/mesh/polyhedra/plato/Cube.java deleted file mode 100644 index 25f5576..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/Cube.java +++ /dev/null @@ -1,87 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * An implementation of a regular cube mesh. - * - * @author Brian Yao - */ -public class Cube extends PlatonicSolid { - - public static Vector3d[] standardPositions(double edgeLength) { - // Generate vertex positions - double halfEdgeLength = edgeLength / 2.0; - Vector3d[] vs = new Vector3d[8]; - for (int i = 0; i < 8; i++) { - Vector3d current = new Vector3d(); - current.x = (i & 1) == 1 ? halfEdgeLength : -halfEdgeLength; - current.y = ((i >> 1) & 1) == 1 ? halfEdgeLength : -halfEdgeLength; - current.z = ((i >> 2) & 1) == 1 ? halfEdgeLength : -halfEdgeLength; - vs[i] = current; - } - return vs; - } - - /** - * Construct a cube mesh centered at the origin with the specified edge - * length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Cube(double edgeLength) { - this(edgeLength, standardPositions(edgeLength)); - } - - public Cube(double edgeLength, Vector3d[] vs) { - super(edgeLength); - - addVertexPositions(vs); - Face f0 = new Face(4); - f0.setAllVertexIndices(0, 2, 3, 1); - - Face f1 = new Face(4); - f1.setAllVertexIndices(0, 4, 6, 2); - - Face f2 = new Face(4); - f2.setAllVertexIndices(0, 1, 5, 4); - - Face f3 = new Face(4); - f3.setAllVertexIndices(7, 6, 4, 5); - - Face f4 = new Face(4); - f4.setAllVertexIndices(7, 5, 1, 3); - - Face f5 = new Face(4); - f5.setAllVertexIndices(7, 3, 2, 6); - - addFaces(f0, f1, f2, f3, f4, f5); - setVertexNormalsToFaceNormals(); - } - - public Cube(Vector3d[] vs) { - super(PlatonicSolid.edgeLength(vs)); - addVertexPositions(vs); - - Face f0 = new Face(4); - Face f1 = new Face(4); - Face f2 = new Face(4); - Face f3 = new Face(4); - Face f4 = new Face(4); - Face f5 = new Face(4); - - f0.setAllVertexIndices(0, 1, 2, 3); - f1.setAllVertexIndices(3, 2, 5, 4); - f2.setAllVertexIndices(3, 4, 7, 0); - - f3.setAllVertexIndices(4, 5, 6, 7); - f4.setAllVertexIndices(1, 0, 7, 6); - f5.setAllVertexIndices(1, 6, 5, 2); - - addFaces(f0, f1, f2, f3, f4, f5); - setVertexNormalsToFaceNormals(); - } -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/Dodecahedron.java b/gui/src/main/java/mesh/polyhedra/plato/Dodecahedron.java deleted file mode 100644 index 9236e23..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/Dodecahedron.java +++ /dev/null @@ -1,151 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * An implementation of a regular dodecahedron mesh. - * - * @author Brian Yao - */ -public class Dodecahedron extends PlatonicSolid { - - private static final double RADIUS_FACTOR = Math.sqrt(3.0) / 4.0 - * (1.0 + Math.sqrt(5)); - - /** - * Construct a dodecahedron mesh centered at the origin with the specified - * edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Dodecahedron(double edgeLength) { - super(edgeLength); - - // Construct vertices - double goldenRatio = (1.0 + Math.sqrt(5.0)) / 2.0; - double goldenRatioInv = 1.0 / goldenRatio; - double edgeScaleFactor = edgeLength / (Math.sqrt(5.0) - 1.0); - Vector3d[] cubePoints = new Vector3d[8]; - for (int i = 0; i < 8; i++) { - Vector3d vcube = new Vector3d(); - vcube.z = (i & 1) == 1 ? -1.0 : 1.0; - vcube.x = ((i >> 1) & 1) == 1 ? -1.0 : 1.0; - vcube.y = ((i >> 2) & 1) == 1 ? -1.0 : 1.0; - vcube.scale(edgeScaleFactor); - cubePoints[i] = vcube; - } - - Vector3d[] greenVertices = new Vector3d[4]; - Vector3d[] pinkVertices = new Vector3d[4]; - Vector3d[] blueVertices = new Vector3d[4]; - for (int i = 0; i < 4; i++) { - Vector3d vgreen = new Vector3d(); - vgreen.x = (i & 1) == 1 ? -goldenRatio : goldenRatio; - vgreen.y = ((i >> 1) & 1) == 1 ? -goldenRatioInv : goldenRatioInv; - vgreen.scale(edgeScaleFactor); - greenVertices[i] = vgreen; - - Vector3d vpink = new Vector3d(); - vpink.z = (i & 1) == 1 ? -goldenRatio : goldenRatio; - vpink.x = ((i >> 1) & 1) == 1 ? -goldenRatioInv : goldenRatioInv; - vpink.scale(edgeScaleFactor); - pinkVertices[i] = vpink; - - Vector3d vblue = new Vector3d(); - vblue.y = (i & 1) == 1 ? -goldenRatio : goldenRatio; - vblue.z = ((i >> 1) & 1) == 1 ? -goldenRatioInv : goldenRatioInv; - vblue.scale(edgeScaleFactor); - blueVertices[i] = vblue; - } - - // Cube points: 0-7, green: 8-11, pink: 12-15, blue: 16-19 - addVertexPositions(cubePoints); - addVertexPositions(greenVertices); - addVertexPositions(pinkVertices); - addVertexPositions(blueVertices); - - Face[] faces = new Face[12]; - for (int i = 0; i < faces.length; i++) { - faces[i] = new Face(5); - } - - // Construct faces - faces[0].setAllVertexIndices(0, 16, 2, 14, 12); - faces[1].setAllVertexIndices(1, 13, 15, 3, 18); - faces[2].setAllVertexIndices(4, 12, 14, 6, 17); - faces[3].setAllVertexIndices(5, 19, 7, 15, 13); - faces[4].setAllVertexIndices(0, 12, 4, 10, 8); - faces[5].setAllVertexIndices(2, 9, 11, 6, 14); - faces[6].setAllVertexIndices(1, 8, 10, 5, 13); - faces[7].setAllVertexIndices(3, 15, 7, 11, 9); - faces[8].setAllVertexIndices(0, 8, 1, 18, 16); - faces[9].setAllVertexIndices(4, 17, 19, 5, 10); - faces[10].setAllVertexIndices(2, 16, 18, 3, 9); - faces[11].setAllVertexIndices(6, 11, 7, 19, 17); - - addFaces(faces); - setVertexNormalsToFaceNormals(); - } - - /** - * Construct a dodecahedron mesh with the specified circumradius. - * - * @param circumradius - * The circumradius this polyhedron will have. - * @param dummy - * A dummy variable. - */ - public Dodecahedron(double circumradius, boolean dummy) { - this(circumradius / RADIUS_FACTOR); - } - - public Dodecahedron(Vector3d[] vertices) { - super(PlatonicSolid.edgeLength(vertices)); - addVertexPositions(vertices); - - Face[] faces = new Face[12]; - for (int i = 0; i < faces.length; i++) { - faces[i] = new Face(5); - } - - @SuppressWarnings("unused") - int[] v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19 }; - @SuppressWarnings("unused") - int[][][] faceMap = { { { 0, 1, 2 }, { 2, 1, 5 }, { 2, 5, 6 } }, - { { 0, 3, 7 }, { 0, 7, 1 }, { 1, 7, 4 } }, - { { 0, 2, 8 }, { 0, 8, 9 }, { 0, 9, 3 } }, - { { 1, 4, 10 }, { 1, 10, 5 }, { 5, 10, 11 } }, - { { 2, 6, 8 }, { 6, 14, 8 }, { 6, 12, 14 } }, - { { 3, 9, 7 }, { 7, 9, 13 }, { 13, 9, 15 } }, - { { 4, 7, 10 }, { 10, 7, 16 }, { 16, 7, 13 } }, - { { 5, 11, 17 }, { 5, 17, 12 }, { 5, 12, 6 } }, - { { 8, 14, 18 }, { 8, 18, 15 }, { 8, 15, 9 } }, - { { 10, 16, 19 }, { 10, 19, 11 }, - { 11, 19, 17 } }, - { { 12, 17, 19 }, { 12, 19, 18 }, - { 12, 18, 14 } }, - { { 13, 15, 18 }, { 13, 18, 19 }, - { 13, 19, 16 } } }; - // Construct faces - faces[0].setAllVertexIndices(0, 1, 6, 5, 2); - faces[1].setAllVertexIndices(0, 3, 7, 1, 4); - faces[2].setAllVertexIndices(0, 2, 8, 9, 3); - faces[3].setAllVertexIndices(1, 4, 10, 5, 11); - faces[4].setAllVertexIndices(2, 6, 8, 14, 12); - faces[5].setAllVertexIndices(3, 9, 7, 13, 15); - faces[6].setAllVertexIndices(4, 7, 10, 16, 13); - faces[7].setAllVertexIndices(5, 11, 17, 12, 6); - faces[8].setAllVertexIndices(8, 14, 18, 15, 9); - faces[9].setAllVertexIndices(10, 16, 19, 11, 17); - faces[10].setAllVertexIndices(12, 17, 19, 18, 14); - faces[11].setAllVertexIndices(13, 15, 18, 19, 16); - - addFaces(faces); - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/Icosahedron.java b/gui/src/main/java/mesh/polyhedra/plato/Icosahedron.java deleted file mode 100644 index b69b4ba..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/Icosahedron.java +++ /dev/null @@ -1,117 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import mesh.Edge; -import mesh.Face; -import mesh.polyhedra.Polyhedron; - -/** - * An implementation of a regular icosahedron mesh. - * - * @author Brian Yao - */ -public class Icosahedron extends PlatonicSolid { - - private static final double RADIUS_FACTOR = Math.sin(2.0 * Math.PI / 5.0); - - /** - * Construct an icosahedron mesh centered at the origin with the specified - * edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Icosahedron(double edgeLength) { - super(edgeLength); - - // An icosahedron is the dual polyhedron of a dodecahedron - Dodecahedron dodec = new Dodecahedron(1.0); - Polyhedron dualDodecahedron = dodec.dual(); - addVertexPositions(dualDodecahedron.getVertexPositions()); - addVertexNormals(dualDodecahedron.getVertexNormals()); - addFaces(dualDodecahedron.getFaces()); - - // Scale vertex positions - Edge sampleEdge = new Edge(faces.get(0) - .getVertexIndex(0), - faces.get(0) - .getVertexIndex(1)); - sampleEdge.setMesh(this); - double scaleFactor = edgeLength / sampleEdge.length(); - for (Vector3d vertexPos : vertexPositions) { - vertexPos.scale(scaleFactor); - } - } - - /** - * Construct a icosahedron mesh with the specified circumradius. - * - * @param circumradius - * The circumradius this polyhedron will have. - * @param dummy - * A dummy variable. - */ - public Icosahedron(double circumradius, boolean dummy) { - this(circumradius / RADIUS_FACTOR); - } - - public Icosahedron(Vector3d[] vs) { - super(PlatonicSolid.edgeLength(vs)); - addVertexPositions(vs); - - Face f0 = new Face(3); - Face f1 = new Face(3); - Face f2 = new Face(3); - Face f3 = new Face(3); - Face f4 = new Face(3); - Face f5 = new Face(3); - Face f6 = new Face(3); - Face f7 = new Face(3); - Face f8 = new Face(3); - Face f9 = new Face(3); - Face f10 = new Face(3); - Face f11 = new Face(3); - Face f12 = new Face(3); - Face f13 = new Face(3); - Face f14 = new Face(3); - Face f15 = new Face(3); - Face f16 = new Face(3); - Face f17 = new Face(3); - Face f18 = new Face(3); - Face f19 = new Face(3); - - int[][] faces = { { 0, 1, 3 }, { 0, 2, 1 }, { 0, 3, 7 }, { 0, 7, 4 }, - { 0, 4, 2 }, { 7, 10, 4 }, { 4, 10, 8 }, { 4, 8, 2 }, - { 2, 8, 5 }, { 2, 5, 1 }, { 1, 5, 6 }, { 1, 6, 3 }, - { 3, 6, 9 }, { 3, 9, 7 }, { 7, 9, 10 }, { 11, 10, 9 }, - { 11, 8, 10 }, { 11, 5, 8 }, { 11, 6, 5 }, - { 11, 9, 6 } }; - - f0.setAllVertexIndices(faces[0]); - f1.setAllVertexIndices(faces[1]); - f2.setAllVertexIndices(faces[2]); - f3.setAllVertexIndices(faces[3]); - f4.setAllVertexIndices(faces[4]); - f5.setAllVertexIndices(faces[5]); - f6.setAllVertexIndices(faces[6]); - f7.setAllVertexIndices(faces[7]); - f8.setAllVertexIndices(faces[8]); - f9.setAllVertexIndices(faces[9]); - f10.setAllVertexIndices(faces[10]); - f11.setAllVertexIndices(faces[11]); - f12.setAllVertexIndices(faces[12]); - f13.setAllVertexIndices(faces[13]); - f14.setAllVertexIndices(faces[14]); - f15.setAllVertexIndices(faces[15]); - f16.setAllVertexIndices(faces[16]); - f17.setAllVertexIndices(faces[17]); - f18.setAllVertexIndices(faces[18]); - f19.setAllVertexIndices(faces[19]); - - addFaces(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, - f14, f15, f16, f17, f18, f19); - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/Octahedron.java b/gui/src/main/java/mesh/polyhedra/plato/Octahedron.java deleted file mode 100644 index 5a87c1c..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/Octahedron.java +++ /dev/null @@ -1,97 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * An implementation of a regular octahedron mesh. - * - * @author Brian Yao - */ -public class Octahedron extends PlatonicSolid { - - private static final double RADIUS_FACTOR = 1.0 / Math.sqrt(2.0); - - public static Vector3d[] standardPositions(double edgeLength) { - // Generate vertices - double distOrigin = edgeLength / Math.sqrt(2.0); - return new Vector3d[] { // The square - new Vector3d(distOrigin, 0.0, 0.0), - new Vector3d(0.0, 0.0, distOrigin), - new Vector3d(-distOrigin, 0.0, 0.0), - new Vector3d(0.0, 0.0, -distOrigin), - - // poles - new Vector3d(0.0, distOrigin, 0.0), - new Vector3d(0.0, -distOrigin, 0.0) }; - } - - /** - * Construct a octahedron mesh centered at the origin with the specified - * edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Octahedron(double edgeLength) { - this(edgeLength, standardPositions(edgeLength)); - } - - /** - * Construct a octahedron mesh with the specified circumradius. - * - * @param circumradius - * The circumradius this polyhedron will have. - * @param dummy - * A dummy variable. - */ - public Octahedron(double circumradius, boolean dummy) { - this(circumradius / RADIUS_FACTOR); - } - - public Octahedron(double edgeLength, Vector3d... vectors) { - super(edgeLength); - addVertexPositions(vectors); - - // Generate faces - for (int i = 0; i < 4; i++) { - int next = (i + 1) % 4; - - Face topFace = new Face(3); - topFace.setAllVertexIndices(4, next, i); - - Face bottomFace = new Face(3); - bottomFace.setAllVertexIndices(5, i, next); - - addFaces(topFace, bottomFace); - } - setVertexNormalsToFaceNormals(); - } - - public Octahedron(Vector3d[] vs) { - super(PlatonicSolid.edgeLength(vs)); - addVertexPositions(vs); - - Face f0 = new Face(3); - Face f1 = new Face(3); - Face f2 = new Face(3); - Face f3 = new Face(3); - Face f4 = new Face(3); - Face f5 = new Face(3); - Face f6 = new Face(3); - Face f7 = new Face(3); - - f0.setAllVertexIndices(5, 4, 2); - f1.setAllVertexIndices(0, 4, 3); - f2.setAllVertexIndices(1, 2, 0); - f3.setAllVertexIndices(5, 1, 3); - f4.setAllVertexIndices(3, 1, 0); - f5.setAllVertexIndices(5, 2, 1); - f6.setAllVertexIndices(5, 3, 4); - f7.setAllVertexIndices(2, 4, 0); - - addFaces(f0, f1, f2, f3, f4, f5, f6, f7); - setVertexNormalsToFaceNormals(); - } -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/PlatonicSolid.java b/gui/src/main/java/mesh/polyhedra/plato/PlatonicSolid.java deleted file mode 100644 index 083791a..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/PlatonicSolid.java +++ /dev/null @@ -1,37 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import math.VectorMath; -import mesh.polyhedra.Polyhedron; - -/** - * Abstract class for a Platonic solid mesh centered at the origin. - * - * @author Brian Yao - */ -public abstract class PlatonicSolid extends Polyhedron { - - public static double edgeLength(Vector3d[] vs) { - Vector3d diff = VectorMath.diff(vs[1], vs[0]); - return diff.length(); - } - - private double edgeLength; - - /** - * @param edgeLength - * The length of each edge in this platonic solid. - */ - public PlatonicSolid(double edgeLength) { - this.edgeLength = edgeLength; - } - - /** - * @return The edge length of each edge in this platonic solid. - */ - public double getEdgeLength() { - return edgeLength; - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/plato/Tetrahedron.java b/gui/src/main/java/mesh/polyhedra/plato/Tetrahedron.java deleted file mode 100644 index 559800d..0000000 --- a/gui/src/main/java/mesh/polyhedra/plato/Tetrahedron.java +++ /dev/null @@ -1,77 +0,0 @@ -package mesh.polyhedra.plato; - -import javax.vecmath.Vector3d; - -import mesh.Face; - -/** - * An implementation of a regular tetrahedron mesh. - * - * @author Brian Yao - */ -public class Tetrahedron extends PlatonicSolid { - - private static final double RADIUS_FACTOR = Math.sqrt(6.0) / 4.0; - - public static Vector3d[] stdPositions(double edgeLength) {// Vertex positions - double edgeScaleFactor = edgeLength / (2.0 * Math.sqrt(2.0)); - Vector3d v0 = new Vector3d(1.0, 1.0, 1.0); - Vector3d v1 = new Vector3d(1.0, -1.0, -1.0); - Vector3d v2 = new Vector3d(-1.0, 1.0, -1.0); - Vector3d v3 = new Vector3d(-1.0, -1.0, 1.0); - v0.scale(edgeScaleFactor); - v1.scale(edgeScaleFactor); - v2.scale(edgeScaleFactor); - v3.scale(edgeScaleFactor); - return new Vector3d[] { v0, v1, v2, v3 }; - } - - public Tetrahedron(boolean inverse, Vector3d... vectors) { - super(PlatonicSolid.edgeLength(vectors)); - assert vectors != null && vectors.length == 4; - addVertexPositions(vectors[0], vectors[1], vectors[2], vectors[3]); - - Face f0 = new Face(3); - Face f1 = new Face(3); - Face f2 = new Face(3); - Face f3 = new Face(3); - if (inverse) { - f0.setAllVertexIndices(1, 3, 0); - f1.setAllVertexIndices(2, 1, 0); - f2.setAllVertexIndices(3, 1, 2); - f3.setAllVertexIndices(3, 2, 0); - } else { - f0.setAllVertexIndices(0, 3, 1); - f1.setAllVertexIndices(0, 1, 2); - f2.setAllVertexIndices(2, 1, 3); - f3.setAllVertexIndices(0, 2, 3); - } - - addFaces(f0, f1, f2, f3); - setVertexNormalsToFaceNormals(); - } - - /** - * Construct a tetrahedron mesh centered at the origin with the specified - * edge length. - * - * @param edgeLength - * The length of each edge of this mesh. - */ - public Tetrahedron(double edgeLength) { - this(false, stdPositions(edgeLength)); - } - - /** - * Construct a tetrahedron mesh with the specified circumradius. - * - * @param circumradius - * The circumradius this polyhedron will have. - * @param dummy - * A dummy variable. - */ - public Tetrahedron(double circumradius, boolean dummy) { - this(circumradius / RADIUS_FACTOR); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/sphere/Goldberg.java b/gui/src/main/java/mesh/polyhedra/sphere/Goldberg.java deleted file mode 100644 index fcb8eed..0000000 --- a/gui/src/main/java/mesh/polyhedra/sphere/Goldberg.java +++ /dev/null @@ -1,39 +0,0 @@ -package mesh.polyhedra.sphere; - -import javax.vecmath.Vector3d; - -import mesh.polyhedra.Polyhedron; - -/** - * An approximate sphere created by projecting the vertices of a Goldberg - * polyhedron to the sphere of desired circumradius. The Goldberg polyhedron is - * generated by taking the dual polyhedron of an icosphere generated with the - * given number of face subdivisions. - * - * @author Brian Yao - */ -public class Goldberg extends Polyhedron { - - /** - * Generate a Goldberg polyhedron whose vertices are projected to the sphere - * of given circumradius and is the dual polyhedron of the icosphere with - * the given number of subdivisions. - * - * @param circumradius - * The distance of vertices from the origin. - * @param subdivisions - * The number of subdivisions in the icosphere. - */ - public Goldberg(double circumradius, int subdivisions) { - Polyhedron ico = new Icosphere(circumradius, subdivisions); - Polyhedron goldberg = ico.dual(); - // Scale all vertices onto the sphere - for (Vector3d vertexPos : goldberg.getVertexPositions()) { - vertexPos.scale(circumradius / vertexPos.length()); - addVertexPosition(vertexPos); - } - addFaces(goldberg.getFaces()); - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/polyhedra/sphere/Icosphere.java b/gui/src/main/java/mesh/polyhedra/sphere/Icosphere.java deleted file mode 100644 index ec01b08..0000000 --- a/gui/src/main/java/mesh/polyhedra/sphere/Icosphere.java +++ /dev/null @@ -1,43 +0,0 @@ -package mesh.polyhedra.sphere; - -import javax.vecmath.Vector3d; - -import mesh.polyhedra.Polyhedron; -import mesh.polyhedra.plato.Icosahedron; - -/** - * An approximate sphere created by using a seed icosahedron and subdividing its - * faces repeatedly, then projecting all vertices to the sphere of the desired - * radius. Each subdivision divides each triangular face into four. - * - * The dual of an icosphere is a Goldberg polyhedron. - * - * @author Brian Yao - */ -public class Icosphere extends Polyhedron { - - /** - * Construct an icosphere with the desired circumradius. - * - * @param circumradius - * The circumradius of the resulting icosphere. - * @param numSubdivisions - * The number of times to subdivide faces. - */ - public Icosphere(double circumradius, int numSubdivisions) { - Polyhedron icosphere = new Icosahedron(circumradius, true); - for (int i = 0; i < numSubdivisions; i++) { - icosphere = icosphere.subdivide(); - } - addFaces(icosphere.getFaces()); - - // Scale all vertices onto the sphere. - for (Vector3d vertexPos : icosphere.getVertexPositions()) { - vertexPos.scale(circumradius / vertexPos.length()); - addVertexPosition(vertexPos); - } - - setVertexNormalsToFaceNormals(); - } - -} diff --git a/gui/src/main/java/mesh/struct/EdgeToAdjacentFace.java b/gui/src/main/java/mesh/struct/EdgeToAdjacentFace.java deleted file mode 100644 index 23e58a1..0000000 --- a/gui/src/main/java/mesh/struct/EdgeToAdjacentFace.java +++ /dev/null @@ -1,69 +0,0 @@ -package mesh.struct; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import mesh.Edge; -import mesh.Face; -import mesh.Mesh; - -/** - * A data structure which computes a mapping from each edge to the two unique - * faces of the mesh which share that edge. The two faces are stored in an array - * of length 2. - * - * @author Brian Yao - */ -public class EdgeToAdjacentFace { - - private Map edgeToFace; - - /** - * Construct a mapping using the geometry in the specified mesh. - * - * @param mesh - * The mesh whose geometry to use to create the mapping. - */ - public EdgeToAdjacentFace(Mesh mesh) { - edgeToFace = new HashMap(); - - // Compute mapping from edge to adjacent faces - for (Face face : mesh.getFaces()) { - Edge[] edges = face.getEdges(); - for (Edge edge : edges) { - Face[] inMap = edgeToFace.get(edge); - if (inMap == null) { - Face[] facePair = new Face[2]; - facePair[0] = face; - edgeToFace.put(edge, facePair); - } else if (inMap[1] == null) { - inMap[1] = face; - } - } - } - } - - /** - * Get the unordered pair of faces which share the specified edge. Returns - * null if no such edge exists in the mesh. - * - * @param edge - * The edge to find adjacent faces of. - * @return An array of two faces which share the specified edge. - */ - public Face[] getAdjacentFaces(Edge edge) { - return edgeToFace.get(edge); - } - - /** - * Get the set of edges we have mapped to adjacent faces. (For a closed - * mesh, this equates to obtaining a set of all edges in the mesh.) - * - * @return The set of mapped edges. - */ - public Set getEdges() { - return edgeToFace.keySet(); - } - -} diff --git a/gui/src/main/java/mesh/struct/FaceToAdjacentFace.java b/gui/src/main/java/mesh/struct/FaceToAdjacentFace.java deleted file mode 100644 index fc33c7d..0000000 --- a/gui/src/main/java/mesh/struct/FaceToAdjacentFace.java +++ /dev/null @@ -1,80 +0,0 @@ -package mesh.struct; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import mesh.Face; -import mesh.Mesh; - -/** - * A data structure which, given a mesh, contains a map from each face in a mesh - * to adjacent faces in the mesh. The adjacent faces will be arranged in the - * same order as the vertices of the face (counterclockwise if the faces follow - * convention). - * - * Two faces are defined to be neighbors if they share an edge (not just one - * vertex). - * - * @author Brian Yao - */ -public class FaceToAdjacentFace { - - private Map> neighborMap; - - /** - * Construct a mapping using the faces in the specified mesh. - * - * @param mesh - * The mesh whose faces to use to create the mapping to neigbors. - */ - public FaceToAdjacentFace(Mesh mesh) { - neighborMap = new HashMap>(); - - // Populate a map which maps vertices to neighboring faces - VertexToAdjacentFace v2af = new VertexToAdjacentFace(mesh); - - // Populate face neighbor map - for (Face face : mesh.getFaces()) { - List neighborList = new ArrayList<>(); - for (int i = 0; i < face.numVertices(); i++) { - int next = (i + 1) % face.numVertices(); - Face neighbor = null; - - // Find neighbor by looking at intersection of the faces neighboring the ith - // vertex and (i + 1)th vertex of the face - for (Face ini : v2af.getAdjacentFaces(face.getVertexIndex(i))) { - if (v2af.getAdjacentFaces(next) - .contains(ini)) { - neighbor = ini; - break; - } - } - - // Add neighbor to list of neighbors - if (neighbor != null) { - neighborList.add(neighbor); - } - } - - if (!neighborList.isEmpty()) { - neighborMap.put(face, neighborList); - } - } - } - - /** - * Get the faces neighboring the specified face in the mesh provided to the - * constructor of this instance. The order of the neighbors is the same as - * the order of the vertices of the specified face. - * - * @param face - * The face whose neighbors to return. - * @return A list of the neighboring faces. - */ - public List getNeighborFaces(Face face) { - return neighborMap.get(face); - } - -} diff --git a/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentEdge.java b/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentEdge.java deleted file mode 100644 index f1a797f..0000000 --- a/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentEdge.java +++ /dev/null @@ -1,86 +0,0 @@ -package mesh.struct; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import mesh.Edge; -import mesh.Face; -import mesh.Mesh; - -/** - * A data structure which, given a mesh, maps each vertex to a list of edges - * which share that vertex as an endpoint. The edges are arranged in the same - * winding order as the vertices of faces. All faces of the mesh must follow the - * same winding order for this to succeed. - * - * For example, by convention, each face has its vertex positions specified in - * counterclockwise order; then, for each vertex, its adjacent edges are listed - * in counterclockwise order as well. - * - * @author Brian Yao - */ -public class OrderedVertexToAdjacentEdge { - - private Map> vertexToEdge; - - /** - * Construct a mapping using the geometry in the specified mesh. - * - * @param mesh - * The mesh whose geometry to use to create the mapping. - */ - public OrderedVertexToAdjacentEdge(Mesh mesh) { - vertexToEdge = new HashMap>(); - - OrderedVertexToAdjacentFace ovtaf = new OrderedVertexToAdjacentFace(mesh); - for (int i : ovtaf.getVertices()) { - List adjacentFaces = ovtaf.getAdjacentFaces(i); - List adjacentEdges = new ArrayList<>(); - for (Face adjFace : adjacentFaces) { - int indOfI = -1; - for (int j = 0; j < adjFace.numVertices(); j++) { - if (adjFace.getVertexIndex(j) == i) { - indOfI = j; - break; - } - } - - int beforeI = indOfI - 1; - if (beforeI < 0) { - beforeI += adjFace.numVertices(); - } - - Edge adjEdge = new Edge(adjFace.getVertexIndex(beforeI), i); - adjEdge.setMesh(mesh); - adjacentEdges.add(adjEdge); - } - vertexToEdge.put(i, adjacentEdges); - } - } - - /** - * Get the list of edges adjacent to the specified vertex. The faces will be - * listed in the same order as the face vertices. - * - * @param vertexIndex - * The index of the vertex whose adjacent edges to return. - * @return A list of edges adjacent to the vertex at the specified index. - */ - public List getAdjacentEdges(int vertexIndex) { - return vertexToEdge.get(vertexIndex); - } - - /** - * Get the set of vertices (or rather, vertex indices) this structure maps - * to lists of adjacent edges. - * - * @return The set of vertices which this structure maps to adjacent edges. - */ - public Set getVertices() { - return vertexToEdge.keySet(); - } - -} diff --git a/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentFace.java b/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentFace.java deleted file mode 100644 index e957379..0000000 --- a/gui/src/main/java/mesh/struct/OrderedVertexToAdjacentFace.java +++ /dev/null @@ -1,117 +0,0 @@ -package mesh.struct; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import mesh.Face; -import mesh.Mesh; - -/** - * A data structure which, given a mesh, maps each vertex to a list of faces - * which contain that vertex. This is different from VertexToAdjacentFace in - * that the faces are arranged in the same winding order as the vertices of - * faces. All faces of the mesh must follow the same winding order for this to - * succeed. - * - * For example, by convention, each face has its vertex positions specified in - * counterclockwise order; then, for each vertex, its adjacent faces are listed - * in counterclockwise order as well. - * - * @author Brian Yao - */ -public class OrderedVertexToAdjacentFace { - - private Map> vertexToFace; - - /** - * Construct a mapping using the geometry in the specified mesh. - * - * @param mesh - * The mesh whose geometry to use to create the mapping. - */ - public OrderedVertexToAdjacentFace(Mesh mesh) { - vertexToFace = new HashMap>(); - VertexToAdjacentFace v2af = new VertexToAdjacentFace(mesh); - - Map indexOfI = new HashMap<>(); - for (int i : v2af.getVertices()) { - Set adjacentFaces = v2af.getAdjacentFaces(i); - indexOfI.clear(); - - if (adjacentFaces != null) { - // Find at which index vertex i appears in each face - for (Face adjFace : adjacentFaces) { - int ind = -1; - - findIndexOfI: for (int j = 0; j < adjFace.numVertices(); j++) { - if (adjFace.getVertexIndex(j) == i) { - ind = j; - break findIndexOfI; - } - } - - indexOfI.put(adjFace, ind); - } - - List orderedAdjacentFaces = new ArrayList<>(); - Face first = adjacentFaces.iterator() - .next(); - orderedAdjacentFaces.add(first); - while (orderedAdjacentFaces.size() < adjacentFaces.size()) { - // In each iteration, find face "next" in order to the last - // element in the current state of the list - Face lastFace = orderedAdjacentFaces.get(orderedAdjacentFaces.size() - - 1); - - // Compute which vertex comes right before vertex i - int indexBeforeI = indexOfI.get(lastFace) - 1; - if (indexBeforeI < 0) { - indexBeforeI += lastFace.numVertices(); - } - int vertexBeforeI = lastFace.getVertexIndex(indexBeforeI); - - // Find next face in order - findNextFace: for (Face adjFace : adjacentFaces) { - if (adjFace != lastFace) { - int indexAfterI = (indexOfI.get(adjFace) + 1) - % adjFace.numVertices(); - int vertexAfterI = adjFace.getVertexIndex(indexAfterI); - if (vertexAfterI == vertexBeforeI) { - orderedAdjacentFaces.add(adjFace); - break findNextFace; - } - } - } - } - - vertexToFace.put(i, orderedAdjacentFaces); - } - } - } - - /** - * Get the list of faces adjacent to the specified vertex. The faces will be - * listed in the same order as the face vertices. - * - * @param vertexIndex - * The index of the vertex whose adjacent faces to return. - * @return A list of faces adjacent to the vertex at the specified index. - */ - public List getAdjacentFaces(int vertexIndex) { - return vertexToFace.get(vertexIndex); - } - - /** - * Get the set of vertices (or rather, vertex indices) this structure maps - * to lists of adjacent faces. - * - * @return The set of vertices which this structure maps to adjacent faces. - */ - public Set getVertices() { - return vertexToFace.keySet(); - } - -} diff --git a/gui/src/main/java/mesh/struct/VertexToAdjacentFace.java b/gui/src/main/java/mesh/struct/VertexToAdjacentFace.java deleted file mode 100644 index 7a58fd4..0000000 --- a/gui/src/main/java/mesh/struct/VertexToAdjacentFace.java +++ /dev/null @@ -1,62 +0,0 @@ -package mesh.struct; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import mesh.Face; -import mesh.Mesh; - -/** - * A data structure which, given a mesh, maps each vertex to the set of faces - * which contain that vertex. The faces are not in any particular order. - * - * @author Brian Yao - */ -public class VertexToAdjacentFace { - - private Map> vertexToFace; - - /** - * Construct a mapping using the geometry in the specified mesh. - * - * @param mesh - * The mesh whose geometry to use to create the mapping. - */ - public VertexToAdjacentFace(Mesh mesh) { - vertexToFace = new HashMap>(); - for (Face face : mesh.getFaces()) { - for (int vertexIndex : face.getVertexIndices()) { - if (vertexToFace.get(vertexIndex) == null) { - vertexToFace.put(vertexIndex, new HashSet()); - } - vertexToFace.get(vertexIndex) - .add(face); - } - } - } - - /** - * Get the set of faces adjacent to the vertex specified by the given index. - * The index is dependent on the mesh provided to the constructor. - * - * @param vertexIndex - * The index of the vertex whose adjacent faces to return. - * @return A set of faces adjacent to the vertex at the specified index. - */ - public Set getAdjacentFaces(int vertexIndex) { - return vertexToFace.get(vertexIndex); - } - - /** - * Get the set of vertices (or rather, vertex indices) this structure maps - * to sets of adjacent faces. - * - * @return The set of vertices which this structure maps to adjacent faces. - */ - public Set getVertices() { - return vertexToFace.keySet(); - } - -} diff --git a/gui/src/main/java/util/Canonicalize.java b/gui/src/main/java/util/Canonicalize.java deleted file mode 100644 index 4ce67d4..0000000 --- a/gui/src/main/java/util/Canonicalize.java +++ /dev/null @@ -1,263 +0,0 @@ -package util; - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.Vector3d; - -import math.VectorMath; -import mesh.Face; -import mesh.polyhedra.Polyhedron; - -/** - * A Java implementation of precisely the iterative algorithm for computing - * canonical polyhedra designed by George W. Hart. All the code in this class is - * based directly off of his work. - * - * Further information on this algorithm and what it does is on Hart's website. - * See this link: http://www.georgehart.com/canonical/canonical-supplement.html - * - * @author Brian Yao - */ -public class Canonicalize { - - private static final double MAX_VERTEX_CHANGE = 1.0; - - /** - * Canonicalizes a polyhedron by adjusting its vertices iteratively. When no - * vertex moves more than the given threshold, the algorithm terminates. - * - * @param poly - * The polyhedron whose vertices to adjust. - * @param threshold - * The threshold of vertex movement after an iteration. - * @return The number of iterations that were executed. - */ - public static int adjust(Polyhedron poly, double threshold) { - return canonicalize(poly, threshold, false); - } - - /** - * Canonicalizes a polyhedron by adjusting its vertices iteratively. - * - * @param poly - * The polyhedron whose vertices to adjust. - * @param numIterations - * The number of iterations to adjust for. - */ - public static void adjust(Polyhedron poly, int numIterations) { - Polyhedron dual = poly.dual(); - for (int i = 0; i < numIterations; i++) { - List newDualPositions = reciprocalCenters(poly); - dual.setVertexPositions(newDualPositions); - List newPositions = reciprocalCenters(dual); - poly.setVertexPositions(newPositions); - } - poly.setVertexNormalsToFaceNormals(); - } - - /** - * Modifies a polyhedron's vertices such that faces are closer to planar. - * When no vertex moves more than the given threshold, the algorithm - * terminates. - * - * @param poly - * The polyhedron to canonicalize. - * @param threshold - * The threshold of vertex movement after an iteration. - * @return The number of iterations that were executed. - */ - public static int planarize(Polyhedron poly, double threshold) { - return canonicalize(poly, threshold, true); - } - - /** - * Modifies a polyhedron's vertices such that faces are closer to planar. - * The more iterations, the closer the faces are to planar. If a vertex - * moves by an unexpectedly large amount, or if the new vertex position has - * an NaN component, the algorithm automatically terminates. - * - * @param poly - * The polyhedron whose faces to planarize. - * @param numIterations - * The number of iterations to planarize for. - */ - public static void planarize(Polyhedron poly, int numIterations) { - Polyhedron dual = poly.dual(); - for (int i = 0; i < numIterations; i++) { - List newDualPositions = reciprocalVertices(poly); - dual.setVertexPositions(newDualPositions); - List newPositions = reciprocalVertices(dual); - - double maxChange = 0.; - for (int j = 0; j < poly.getVertexPositions() - .size(); j++) { - Vector3d newPos = poly.getVertexPositions() - .get(j); - Vector3d diff = VectorMath.diff(newPos, - poly.getVertexPositions() - .get(j)); - maxChange = Math.max(maxChange, diff.length()); - } - - // Check if an error occurred in computation. If so, terminate - // immediately. This likely occurs when faces are already planar. - if (VectorMath.isNaN(newPositions.get(0))) { - break; - } - - // Check if the position changed by a significant amount so as to - // be erroneous. If so, terminate immediately - if (maxChange > MAX_VERTEX_CHANGE) { - break; - } - - poly.setVertexPositions(newPositions); - } - poly.setVertexNormalsToFaceNormals(); - } - - /** - * A helper method for threshold-based termination in both planarizing and - * adjusting. If a vertex moves by an unexpectedly large amount, or if the - * new vertex position has an NaN component, the algorithm automatically - * terminates. - * - * @param poly - * The polyhedron to canonicalize. - * @param threshold - * The threshold of vertex movement after an iteration. - * @param planarize - * True if we are planarizing, false if we are adjusting. - * @return The number of iterations that were executed. - */ - private static int canonicalize(Polyhedron poly, double threshold, - boolean planarize) { - Polyhedron dual = poly.dual(); - List currentPositions = Struct.copyVectorList(poly.getVertexPositions()); - - int iterations = 0; - while (true) { - List newDualPositions = planarize ? reciprocalVertices(poly) - : reciprocalCenters(poly); - dual.setVertexPositions(newDualPositions); - List newPositions = planarize ? reciprocalVertices(dual) - : reciprocalCenters(dual); - - double maxChange = 0.; - for (int i = 0; i < currentPositions.size(); i++) { - Vector3d newPos = poly.getVertexPositions() - .get(i); - Vector3d diff = VectorMath.diff(newPos, - currentPositions.get(i)); - maxChange = Math.max(maxChange, diff.length()); - } - - // Check if an error occurred in computation. If so, terminate - // immediately - if (VectorMath.isNaN(newPositions.get(0))) { - break; - } - - // Check if the position changed by a significant amount so as to - // be erroneous. If so, terminate immediately - if (planarize && maxChange > MAX_VERTEX_CHANGE) { - break; - } - - poly.setVertexPositions(newPositions); - - if (maxChange < threshold) { - break; - } - - currentPositions = Struct.copyVectorList(poly.getVertexPositions()); - iterations++; - } - - poly.setVertexNormalsToFaceNormals(); - return iterations; - } - - /** - * A port of the "reciprocalC" function written by George Hart. Reflects the - * centers of faces across the unit sphere. - * - * @param poly - * The polyhedron whose centers to invert. - * @return The list of inverted face centers. - */ - private static List reciprocalCenters(Polyhedron poly) { - List faceCenters = new ArrayList<>(); - for (Face face : poly.getFaces()) { - Vector3d newCenter = new Vector3d(face.vertexAverage()); - newCenter.scale(1.0 / newCenter.lengthSquared()); - faceCenters.add(newCenter); - } - return faceCenters; - } - - /** - * A port of the "reciprocalN" function written by George Hart. - * - * @param poly - * The polyhedron to apply this canonicalization to. - * @return A list of the new vertices of the dual polyhedron. - */ - private static List reciprocalVertices(Polyhedron poly) { - List newVertices = new ArrayList<>(); - - List vertexPositions = poly.getVertexPositions(); - for (Face face : poly.getFaces()) { - // Initialize values which will be updated in the loop below - Vector3d centroid = face.vertexAverage(); - Vector3d normalSum = new Vector3d(); - double avgEdgeDistance = 0.; - - // Retrieve the indices of the vertices defining this face - int[] faceVertexIndices = face.getVertexIndices(); - - // Keep track of the "previous" two vertices in CCW order - int lastLastVertexIndex = faceVertexIndices[faceVertexIndices.length - - 2]; - int lastVertexIndex = faceVertexIndices[faceVertexIndices.length - - 1]; - for (int vertexIndex : faceVertexIndices) { - Vector3d vertex = vertexPositions.get(vertexIndex); - - // Compute the normal of the plane defined by this vertex and - // the previous two - Vector3d lastlastVertex = vertexPositions.get(lastLastVertexIndex); - Vector3d lastVertex = vertexPositions.get(lastVertexIndex); - Vector3d v1 = new Vector3d(lastlastVertex); - v1.sub(lastVertex); - Vector3d v2 = new Vector3d(vertex); - v2.sub(lastVertex); - Vector3d normal = new Vector3d(); - normal.cross(v1, v2); - normalSum.add(normal); - - // Compute distance from edge to origin - avgEdgeDistance += Geometry.pointLineDist(new Vector3d(), - lastlastVertex, - lastVertex); - - // Update the previous vertices for the next iteration - lastLastVertexIndex = lastVertexIndex; - lastVertexIndex = vertexIndex; - } - - normalSum.normalize(); - avgEdgeDistance /= faceVertexIndices.length; - - Vector3d resultingVector = new Vector3d(); - resultingVector.scale(centroid.dot(normalSum), normalSum); - resultingVector.scale(1.0 / resultingVector.lengthSquared()); - resultingVector.scale((1.0 + avgEdgeDistance) / 2.0); - newVertices.add(resultingVector); - } - - return newVertices; - } - -} diff --git a/gui/src/main/java/util/Geometry.java b/gui/src/main/java/util/Geometry.java deleted file mode 100644 index 2cc3c27..0000000 --- a/gui/src/main/java/util/Geometry.java +++ /dev/null @@ -1,60 +0,0 @@ -package util; - -import javax.vecmath.Vector3d; - -/** - * A utility class involving geometric computations. - * - * @author Brian Yao - */ -public class Geometry { - - /** - * Computes the distance from a point to a line in 3D. - * - * @param point - * The point we are calculating distance from. - * @param linePoint1 - * The first of two points defining the line. - * @param linePoint2 - * The second of two points defining the line. - * @return The distance of point from the line defined by the two line - * points. - */ - public static double pointLineDist(Vector3d point, Vector3d linePoint1, - Vector3d linePoint2) { - return Math.sqrt(pointLineDistSq(point, linePoint1, linePoint2)); - } - - /** - * Computes the square of the distance from a point to a line in 3D. - * - * @param point - * The point we are calculating distance from. - * @param linePoint1 - * The first of two points defining the line. - * @param linePoint2 - * The second of two points defining the line. - * @return The square of the distance of point from the line defined by the - * two line points. - */ - public static double pointLineDistSq(Vector3d point, Vector3d linePoint1, - Vector3d linePoint2) { - Vector3d lineVector = new Vector3d(); - lineVector.sub(linePoint2, linePoint1); - Vector3d linePointVector = new Vector3d(); - linePointVector.sub(linePoint1, point); - double lineVectorLengthSq = lineVector.lengthSquared(); - - if (lineVectorLengthSq == 0) { - return linePointVector.lengthSquared(); - } else { - Vector3d scaledLineVector = new Vector3d(); - scaledLineVector.scale(linePointVector.dot(lineVector), lineVector); - Vector3d distanceVector = new Vector3d(); - distanceVector.sub(linePointVector, scaledLineVector); - return distanceVector.lengthSquared(); - } - } - -} diff --git a/gui/src/main/java/util/PolyhedraUtils.java b/gui/src/main/java/util/PolyhedraUtils.java deleted file mode 100644 index 4a2dc0b..0000000 --- a/gui/src/main/java/util/PolyhedraUtils.java +++ /dev/null @@ -1,177 +0,0 @@ -package util; - -import java.util.HashMap; -import java.util.Map; - -import javax.vecmath.Vector3d; - -import math.VectorMath; -import mesh.Edge; -import mesh.Face; -import mesh.polyhedra.Polyhedron; - -/** - * A utility class for polyhedra. - * - * @author Brian Yao - */ -public class PolyhedraUtils { - - /** - * Generates new vertices on each face located midway on the line segment - * whose endpoints are the face's centroid and the midpoint of one of the - * edges bordering that face. For a face with n sides, n new vertices are - * generated for that face. - * - * The new vertices are generated using the faces in the "source" - * polyhedron, and added to the "modify" polyhedron (see params). To do this - * in-place, ensure that source and modify refer to the same polyhedron. - * - * A map is returned to help keep track of the vertex indices of the new - * vertices. The map is structured such that it maps an ordered pair (a,b) - * of integers to another integer c. The integer c is the index of one of - * the newly generated points midway between the midpoint of the edge (a,b) - * and the centroid of the face to the left of (a,b). This notion of "left" - * is defined by the face for which following the vertices in the order of a - * -> b -> c -> a defines a traversal of the perimeter of triangle (a,b,c) - * in counterclockwise order (as seen from outside the face). This is why we - * map ordered pairs, so that (a,b) is mapped to the new vertex of one face, - * and (b,a) is mapped to the new vertex on the other face. - * - * @param source - * The polyhedron whose faces to use as input. - * @param modify - * The polyhedron to add the new vertices to. - * @return A map from edges to new vertices as described above. - */ - public static Map> addEdgeToCentroidVertices(Polyhedron source, - Polyhedron modify) { - int vertexIndex = modify.numVertexPositions(); - Map> edgeToVertex = new HashMap<>(); - for (Face face : source.getFaces()) { - Vector3d centroid = face.centroid(); - Edge[] edges = face.getEdges(); - int[] newFaceVertices = new int[face.numVertices()]; - - // Generate new vertices partway from edge midpoint to face centroid - for (int i = 0; i < edges.length; i++) { - Vector3d edgeMidpt = edges[i].midpoint(); - Vector3d newVertex = VectorMath.interpolate(edgeMidpt, centroid, - 0.3); // 0 < arbitrary scale factor < 1 - - modify.addVertexPosition(newVertex); - newFaceVertices[i] = vertexIndex++; - } - - // Populate map from edge to new vertices - for (int i = 0; i < edges.length; i++) { - int[] ends = edges[i].getEnds(); - edgeToVertex.computeIfAbsent(ends[0], - a -> new HashMap()); - edgeToVertex.get(ends[0]) - .put(ends[1], newFaceVertices[i]); - } - } - - return edgeToVertex; - } - - /** - * Generates rhombic faces in place of the edges in the source polyhedron. - * This requires new vertices on each face. These new vertices are assumed - * to be precomputed by - * {@link util.PolyhedraUtils#addEdgeToCentroidVertices(Polyhedron, Polyhedron)} - * and are inputs to this method as the third parameter. - * - * The new faces are added to the "modify" polyhedron (see params). - * - * @param source - * The polyhedron whose edges to use as input. - * @param modify - * The polyhedron to add the new faces to. - * @param edgeToVertex - * The map of new vertices, as returned by - * {@link util.PolyhedraUtils#addEdgeToCentroidVertices(Polyhedron, Polyhedron)}. - */ - public static void addRhombicFacesAtEdges(Polyhedron source, - Polyhedron modify, - Map> edgeToVertex) { - // Create rhombic faces - for (Edge edge : source.getEdges()) { - Face rhombus = new Face(4); - int[] ends = edge.getEnds(); - int v0 = edgeToVertex.get(ends[0]) - .get(ends[1]); - int v2 = edgeToVertex.get(ends[1]) - .get(ends[0]); - rhombus.setAllVertexIndices(v0, ends[0], v2, ends[1]); - - modify.addFace(rhombus); - } - } - - /** - * Generates equally spaced vertices along each edge such that each edge is - * divided into n equal segments, where n is the "segments" parameter. The - * number of vertices added per edge is one less than the "segments" - * parameter. - * - * For each edge (a,b) where a and b are vertex indices, an entry of the map - * will map a to another map, which maps b to an array containing the - * indices of the new vertices along the edge (a,b). The array will be in - * order, with the first index being the vertex closest to a, and the last - * index being the vertex closest to b. The reverse mapping is also present, - * with (b,a) being mapped to the same array, but reversed. The length of - * each array is one less than the "segments" parameter. - * - * @param source - * The polyhedron whose edges to use. - * @param modify - * The polyhedron we are adding the new vertices to. - * @param segments - * The number of segments to divide each edge into. - * @return The mapping of each edge to the new vertices along it. - */ - public static Map> subdivideEdges(Polyhedron source, - Polyhedron modify, - int segments) { - Map> newVertices = new HashMap<>(); - int vertexIndex = modify.getVertexPositions() - .size(); // next index - for (Edge edge : source.getEdges()) { - int[] ends = edge.getEnds(); - - Vector3d[] endPositions = edge.getEndLocations(); - - int[] newIndices = new int[segments - 1]; - int[] newIndicesReverse = new int[segments - 1]; - - // Generate and add vertices for this edge - double denom = segments; - for (int i = 1; i <= segments - 1; i++) { - Vector3d newVertex = VectorMath.interpolate(endPositions[0], - endPositions[1], - i / denom); - - modify.addVertexPosition(newVertex); - newIndices[i - 1] = vertexIndex; - newIndicesReverse[segments - i - 1] = vertexIndex; - vertexIndex++; - } - - // Map the existing edge to the new vertices along it - newVertices.computeIfAbsent(ends[0], - a -> new HashMap()); - newVertices.get(ends[0]) - .put(ends[1], newIndices); - - newVertices.computeIfAbsent(ends[1], - a -> new HashMap()); - newVertices.get(ends[1]) - .put(ends[0], newIndicesReverse); - } - - return newVertices; - } - -} diff --git a/gui/src/main/java/util/Struct.java b/gui/src/main/java/util/Struct.java deleted file mode 100644 index 3f1cdbe..0000000 --- a/gui/src/main/java/util/Struct.java +++ /dev/null @@ -1,30 +0,0 @@ -package util; - -import java.util.ArrayList; -import java.util.List; - -import javax.vecmath.Vector3d; - -/** - * Utility class for data structure related operations. - * - * @author Brian Yao - */ -public class Struct { - - /** - * Deep copy of a list of 3D vectors. - * - * @param vectors - * The list of vectors to be copied. - * @return A copy of the list of vectors. - */ - public static List copyVectorList(List vectors) { - List copies = new ArrayList<>(); - for (Vector3d vector : vectors) { - copies.add(new Vector3d(vector)); - } - return copies; - } - -}