diff --git a/README.md b/README.md new file mode 100644 index 0000000..e229f1f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# IHMC JavaFX Toolkit + +[ ![Download](https://api.bintray.com/packages/ihmcrobotics/maven-release/ihmc-javafx-toolkit/images/download.svg) ](https://bintray.com/ihmcrobotics/maven-release/ihmc-javafx-toolkit/_latestVersion) \ No newline at end of file diff --git a/build.gradle b/build.gradle index 49c7d0e..0424c9d 100644 --- a/build.gradle +++ b/build.gradle @@ -4,14 +4,14 @@ buildscript { mavenLocal() } dependencies { - classpath "us.ihmc:ihmc-build:0.13.7" + classpath "us.ihmc:ihmc-build:0.14.0" } } apply plugin: "us.ihmc.ihmc-build" ihmc { group = "us.ihmc" - version = "0.12.2" + version = "0.12.3" vcsUrl = "https://github.com/ihmcrobotics/ihmc-javafx-toolkit" openSource = true diff --git a/gradle.properties b/gradle.properties index 904d21f..c410ebc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ pascalCasedName = IHMCJavaFXToolkit extraSourceSets = ["test", "visualizers"] publishUrl = local compositeSearchHeight = 0 -excludeFromCompositeBuild = true \ No newline at end of file +excludeFromCompositeBuild = false \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 3c7ae0a..dac92a3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,7 +4,7 @@ buildscript { mavenLocal() } dependencies { - classpath "us.ihmc:ihmc-build:0.13.7" + classpath "us.ihmc:ihmc-build:0.14.0" } } diff --git a/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphics3DNode.java b/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphics3DNode.java index d60aa6e..8d57c36 100644 --- a/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphics3DNode.java +++ b/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphics3DNode.java @@ -7,6 +7,7 @@ import javafx.scene.transform.Affine; import javafx.scene.transform.Transform; import us.ihmc.euclid.transform.AffineTransform; +import us.ihmc.graphicsDescription.appearance.AppearanceDefinition; import us.ihmc.graphicsDescription.structure.Graphics3DNode; import us.ihmc.javaFXToolkit.JavaFXTools; @@ -17,10 +18,15 @@ public class JavaFXGraphics3DNode extends Group private final ArrayList updatables = new ArrayList<>(); public JavaFXGraphics3DNode(Graphics3DNode graphicsNode) + { + this(graphicsNode, null); + } + + public JavaFXGraphics3DNode(Graphics3DNode graphicsNode, AppearanceDefinition appearance) { this.graphicsNode = graphicsNode; - javaFXGraphicsObject = new JavaFXGraphicsObject(graphicsNode.getGraphics3DObject()); + javaFXGraphicsObject = new JavaFXGraphicsObject(graphicsNode.getGraphics3DObject(), appearance); this.getChildren().add(javaFXGraphicsObject.getGroup()); } @@ -33,8 +39,8 @@ public void update() AffineTransform euclidAffineTransform = graphicsNode.getTransform(); JavaFXTools.convertEuclidAffineToJavaFXAffine(euclidAffineTransform, javaFxAffineTransform); transforms.add(javaFxAffineTransform); - - for(int i = 0; i < updatables.size(); i++) + + for (int i = 0; i < updatables.size(); i++) { updatables.get(i).update(); } diff --git a/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphicsObject.java b/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphicsObject.java index 318329f..e17ab7f 100644 --- a/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphicsObject.java +++ b/src/main/java/us/ihmc/javaFXToolkit/node/JavaFXGraphicsObject.java @@ -32,6 +32,7 @@ import us.ihmc.graphicsDescription.instructions.Graphics3DAddHeightMapInstruction; import us.ihmc.graphicsDescription.instructions.Graphics3DAddMeshDataInstruction; import us.ihmc.graphicsDescription.instructions.Graphics3DAddModelFileInstruction; +import us.ihmc.graphicsDescription.instructions.Graphics3DInstruction; import us.ihmc.graphicsDescription.instructions.Graphics3DInstructionExecutor; import us.ihmc.graphicsDescription.instructions.Graphics3DPrimitiveInstruction; import us.ihmc.graphicsDescription.instructions.HemiEllipsoidGraphics3DInstruction; @@ -49,18 +50,30 @@ public class JavaFXGraphicsObject extends Graphics3DInstructionExecutor { - -// private static float r; private final Group parentGroup = new Group(); private Group currentGroup = parentGroup; public JavaFXGraphicsObject(Graphics3DObject graphics3dObject) { - if(graphics3dObject != null) + this(graphics3dObject, null); + } + + public JavaFXGraphicsObject(Graphics3DObject graphics3dObject, AppearanceDefinition appearance) + { + if (graphics3dObject != null) { ArrayList graphics3dInstructions = graphics3dObject.getGraphics3DInstructions(); - if(graphics3dInstructions != null) + if (graphics3dInstructions != null) { + for (Graphics3DPrimitiveInstruction instruction : graphics3dInstructions) + { + if (instruction instanceof Graphics3DInstruction) + { + Graphics3DInstruction graphicsInstruction = (Graphics3DInstruction) instruction; + if (appearance != null) + graphicsInstruction.setAppearance(appearance); + } + } setUpGraphicsFromDefinition(graphics3dInstructions); } } @@ -105,6 +118,16 @@ protected void doAddModelFileInstruction(Graphics3DAddModelFileInstruction graph { e.printStackTrace(); } + + if (graphics3DAddModelFile.getAppearance() != null) + { + Material outputMaterial = convertMaterial(graphics3DAddModelFile.getAppearance()); + for (int i = 0; i < outputModelMeshes.length; i++) + { + outputModelMeshes[i].setMaterial(outputMaterial); + } + } + Group meshGroup = new Group(outputModelMeshes); currentGroup.getChildren().add(meshGroup); currentGroup = meshGroup; @@ -146,7 +169,7 @@ protected void doTranslateInstruction(Graphics3DTranslateInstruction graphics3DT { Vector3D t = graphics3DTranslate.getTranslation(); Translate outputTranslation = new Translate(t.getX(), t.getY(), t.getZ()); - + Group translationGroup = new Group(); translationGroup.getTransforms().add(outputTranslation); currentGroup.getChildren().add(translationGroup); @@ -165,7 +188,7 @@ private static Material convertMaterial(AppearanceDefinition appearance) float b = appearance.getColor().getZ(); double transparency = appearance.getTransparency(); - if(appearance instanceof YoAppearanceRGBColor) + if (appearance instanceof YoAppearanceRGBColor) { transparency = 1.0 - transparency; } @@ -189,7 +212,7 @@ protected void doAddPrimitiveInstruction(PrimitiveGraphics3DInstruction primitiv CubeGraphics3DInstruction cubeInstruction = (CubeGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.Cube(cubeInstruction.getLength(), cubeInstruction.getWidth(), cubeInstruction.getHeight(), - cubeInstruction.getCenteredInTheCenter(), cubeInstruction.getTextureFaces()); + cubeInstruction.getCenteredInTheCenter(), cubeInstruction.getTextureFaces()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, cubeInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); @@ -199,7 +222,7 @@ else if (primitiveInstruction instanceof SphereGraphics3DInstruction) SphereGraphics3DInstruction sphereInstruction = (SphereGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.Sphere(sphereInstruction.getRadius(), sphereInstruction.getResolution(), - sphereInstruction.getResolution()); + sphereInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, sphereInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); @@ -218,7 +241,8 @@ else if (primitiveInstruction instanceof CapsuleGraphics3DInstruction) CapsuleGraphics3DInstruction capsuleInstruction = (CapsuleGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.Capsule(capsuleInstruction.getHeight(), capsuleInstruction.getXRadius(), capsuleInstruction.getYRadius(), - capsuleInstruction.getZRadius(), capsuleInstruction.getResolution(), capsuleInstruction.getResolution()); + capsuleInstruction.getZRadius(), capsuleInstruction.getResolution(), + capsuleInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, capsuleInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); @@ -228,7 +252,8 @@ else if (primitiveInstruction instanceof EllipsoidGraphics3DInstruction) EllipsoidGraphics3DInstruction ellipsoidInstruction = (EllipsoidGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.Ellipsoid(ellipsoidInstruction.getXRadius(), ellipsoidInstruction.getYRadius(), - ellipsoidInstruction.getZRadius(), ellipsoidInstruction.getResolution(), ellipsoidInstruction.getResolution()); + ellipsoidInstruction.getZRadius(), ellipsoidInstruction.getResolution(), + ellipsoidInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, ellipsoidInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -237,7 +262,7 @@ else if (primitiveInstruction instanceof CylinderGraphics3DInstruction) CylinderGraphics3DInstruction cylinderInstruction = (CylinderGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.Cylinder(cylinderInstruction.getRadius(), cylinderInstruction.getHeight(), - cylinderInstruction.getResolution()); + cylinderInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, cylinderInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -254,8 +279,8 @@ else if (primitiveInstruction instanceof TruncatedConeGraphics3DInstruction) TruncatedConeGraphics3DInstruction truncatedConeInstruction = (TruncatedConeGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.GenTruncatedCone(truncatedConeInstruction.getHeight(), truncatedConeInstruction.getXBaseRadius(), - truncatedConeInstruction.getYBaseRadius(), truncatedConeInstruction.getXTopRadius(), truncatedConeInstruction.getYTopRadius(), - truncatedConeInstruction.getResolution()); + truncatedConeInstruction.getYBaseRadius(), truncatedConeInstruction.getXTopRadius(), + truncatedConeInstruction.getYTopRadius(), truncatedConeInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, truncatedConeInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -264,7 +289,8 @@ else if (primitiveInstruction instanceof HemiEllipsoidGraphics3DInstruction) HemiEllipsoidGraphics3DInstruction hemiEllipsoidInstruction = (HemiEllipsoidGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.HemiEllipsoid(hemiEllipsoidInstruction.getXRadius(), hemiEllipsoidInstruction.getYRadius(), - hemiEllipsoidInstruction.getZRadius(), hemiEllipsoidInstruction.getResolution(), hemiEllipsoidInstruction.getResolution()); + hemiEllipsoidInstruction.getZRadius(), hemiEllipsoidInstruction.getResolution(), + hemiEllipsoidInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, hemiEllipsoidInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -273,7 +299,8 @@ else if (primitiveInstruction instanceof ArcTorusGraphics3DInstruction) ArcTorusGraphics3DInstruction arcTorusInstruction = (ArcTorusGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.ArcTorus(arcTorusInstruction.getStartAngle(), arcTorusInstruction.getEndAngle(), - arcTorusInstruction.getMajorRadius(), arcTorusInstruction.getMinorRadius(), arcTorusInstruction.getResolution()); + arcTorusInstruction.getMajorRadius(), arcTorusInstruction.getMinorRadius(), + arcTorusInstruction.getResolution()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, arcTorusInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -282,7 +309,7 @@ else if (primitiveInstruction instanceof PyramidCubeGraphics3DInstruction) PyramidCubeGraphics3DInstruction pyramidInstruction = (PyramidCubeGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.PyramidCube(pyramidInstruction.getLengthX(), pyramidInstruction.getWidthY(), - pyramidInstruction.getHeightZ(), pyramidInstruction.getPyramidHeight()); + pyramidInstruction.getHeightZ(), pyramidInstruction.getPyramidHeight()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, pyramidInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } @@ -299,9 +326,9 @@ else if (primitiveInstruction instanceof ExtrudedPolygonGraphics3DInstruction) ExtrudedPolygonGraphics3DInstruction extrudedPolygonInstruction = (ExtrudedPolygonGraphics3DInstruction) primitiveInstruction; MeshDataHolder meshData = MeshDataGenerator.ExtrudedPolygon(extrudedPolygonInstruction.getPolygonPoints(), - extrudedPolygonInstruction.getExtrusionHeight()); + extrudedPolygonInstruction.getExtrusionHeight()); Graphics3DAddMeshDataInstruction meshDataInstruction = Graphics3DObject.createMeshDataInstruction(meshData, - extrudedPolygonInstruction.getAppearance()); + extrudedPolygonInstruction.getAppearance()); doAddMeshDataInstruction(meshDataInstruction); } else diff --git a/src/test/java/us/ihmc/javaFXGraphics/JavaFXGraphicsTest.java b/src/test/java/us/ihmc/javaFXGraphics/JavaFXGraphicsTest.java new file mode 100644 index 0000000..cdf7cbe --- /dev/null +++ b/src/test/java/us/ihmc/javaFXGraphics/JavaFXGraphicsTest.java @@ -0,0 +1,56 @@ +package us.ihmc.javaFXGraphics; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; + +import org.junit.Test; + +import us.ihmc.continuousIntegration.ContinuousIntegrationAnnotations.ContinuousIntegrationPlan; +import us.ihmc.continuousIntegration.ContinuousIntegrationAnnotations.ContinuousIntegrationTest; +import us.ihmc.continuousIntegration.IntegrationCategory; +import us.ihmc.euclid.tuple3D.Vector3D; +import us.ihmc.graphicsDescription.Graphics3DObject; +import us.ihmc.graphicsDescription.appearance.AppearanceDefinition; +import us.ihmc.graphicsDescription.appearance.YoAppearance; +import us.ihmc.graphicsDescription.color.MutableColor; +import us.ihmc.graphicsDescription.instructions.Graphics3DInstruction; +import us.ihmc.graphicsDescription.instructions.Graphics3DPrimitiveInstruction; +import us.ihmc.javaFXToolkit.node.JavaFXGraphicsObject; + +@ContinuousIntegrationPlan(categories = {IntegrationCategory.FAST}) +public class JavaFXGraphicsTest +{ + private static final double CUBE_SIDE = 2.0; + private static final double CUBE_X = 5.0; + + private static final AppearanceDefinition desiredAppearance = YoAppearance.Red(); + + @ContinuousIntegrationTest(estimatedDuration = 1.0) + @Test(timeout = 30000) + public void testJavaFXGraphicsObject() + { + Graphics3DObject cubeGraphics = new Graphics3DObject(); + cubeGraphics.translate(new Vector3D(CUBE_X, 0.0, 0.0)); + cubeGraphics.addCube(CUBE_SIDE, CUBE_SIDE, CUBE_SIDE); + + JavaFXGraphicsObject javaFXGraphics = new JavaFXGraphicsObject(cubeGraphics, desiredAppearance); + + ArrayList graphics3dInstructions = cubeGraphics.getGraphics3DInstructions(); + for (Graphics3DPrimitiveInstruction primitive : graphics3dInstructions) + { + if (primitive instanceof Graphics3DInstruction) + { + Graphics3DInstruction graphicsInstruction = (Graphics3DInstruction) primitive; + AppearanceDefinition appearance = graphicsInstruction.getAppearance(); + MutableColor actualColor = appearance.getColor(); + MutableColor expectedColor = desiredAppearance.getColor(); + assertTrue(actualColor.x == expectedColor.x); + assertTrue(actualColor.y == expectedColor.y); + assertTrue(actualColor.z == expectedColor.z); + } + } + + System.out.print(javaFXGraphics.getClass().getSimpleName() + " propely set up graphics from instructions."); + } +}