/** * TexturedMeshSample.java * * Copyright (c) 2013-2016, F(X)yz * All rights reserved. * * 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 F(X)yz, any associated website, 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 F(X)yz 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 org.fxyz3d.samples.shapes; import java.util.function.Function; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.image.Image; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import org.fxyz3d.controls.TextureImage; import org.fxyz3d.geometry.Point3D; import org.fxyz3d.scene.paint.Patterns.CarbonPatterns; import org.fxyz3d.shapes.primitives.TexturedMesh; import org.fxyz3d.shapes.primitives.helper.TriangleMeshHelper; import org.fxyz3d.shapes.primitives.helper.TriangleMeshHelper.TextureType; import org.fxyz3d.tools.NormalMap; /** * * @author Jason Pollastrini aka jdub1581 */ public abstract class TexturedMeshSample extends ShapeBaseSample<TexturedMesh> { //specific protected final Property<TriangleMeshHelper.SectionType> sectionType = new SimpleObjectProperty<TriangleMeshHelper.SectionType>(model, "secType", TriangleMeshHelper.SectionType.CIRCLE) { @Override protected void invalidated() { super.invalidated(); if (model != null) { model.setSectionType(sectionType.getValue()); } } }; protected final Property<TextureType> textureType = new SimpleObjectProperty<TextureType>(model, "texType", TriangleMeshHelper.TextureType.NONE) { @Override protected void invalidated() { super.invalidated(); if (model != null) { switch (getValue()) { case NONE: model.setTextureModeNone(colorBinding.get()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; case IMAGE: model.setTextureModeImage(textureImage.getValue()==null?null:textureImage.getValue().getSource()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; case PATTERN: model.setTextureModePattern(patterns.get(), pattScale.getValue()); material.setSpecularColor(specColorBinding.get()); material.setSpecularPower(specularPower.doubleValue()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; case COLORED_VERTICES_1D: model.setTextureModeVertices1D(1530, func.getValue()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; case COLORED_VERTICES_3D: model.setTextureModeVertices3D(1530, dens.getValue()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; case COLORED_FACES: model.setTextureModeFaces(1530); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } break; } } } }; /* TriangleMeshHelper.TextureType.NONE */ protected final ObjectProperty<Color> colorBinding = new SimpleObjectProperty<Color>(Color.BROWN) { @Override protected void invalidated() { super.invalidated(); if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.NONE)) { model.setDiffuseColor(get()); } } }; protected final IntegerProperty colors = new SimpleIntegerProperty(model, "Color :", 700) { @Override protected void invalidated() { super.invalidated(); if (model != null) { colorBinding.set(Color.hsb(360 * (1d - get() / 1530d), 1, 0.5)); } } }; /* TriangleMeshHelper.TextureType.IMAGE */ protected final Property<TextureImage> textureImage = new SimpleObjectProperty(this, "Texture") { @Override protected void invalidated() { if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.IMAGE)) { //material.setDiffuseMap(textureImage.getValue()); model.setTextureModeImage(textureImage.getValue().getSource()); if (useBumpMap.getValue() || invert.getValue()) { useBumpMap.setValue(false); invert.setValue(false); } } } }; protected final ObjectProperty<CarbonPatterns> patterns = new SimpleObjectProperty<CarbonPatterns>(CarbonPatterns.DARK_CARBON) { @Override protected void invalidated() { super.invalidated(); if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.PATTERN)) { model.setCarbonPattern(patterns.getValue()); material.setSpecularColor(specColorBinding.get()); material.setSpecularPower(specularPower.doubleValue()); if (useBumpMap.get()) { material.setBumpMap(new NormalMap( bumpScale.doubleValue(), bumpFineScale.doubleValue(), invert.getValue(), ((PhongMaterial) model.getMaterial()).getDiffuseMap() )); } } } }; /* TriangleMeshHelper.TextureType.PATTERN */ protected final DoubleProperty pattScale = new SimpleDoubleProperty(this, "Pattern Scale: ", 2.0d) { @Override protected void invalidated() { super.invalidated(); if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.PATTERN)) { model.setPatternScale(pattScale.doubleValue()); } } }; /* TriangleMeshHelper.TextureType.COLORED_VERTICES_3D */ protected final DoubleProperty densMax = new SimpleDoubleProperty(this, "Density Scale: "); protected final Property<Function<Point3D, Number>> dens = new SimpleObjectProperty<Function<Point3D, Number>>(p -> p.x * p.y * p.z) { @Override protected void invalidated() { super.invalidated(); if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.COLORED_VERTICES_3D)) { model.setDensity(dens.getValue()); } } }; /* TriangleMeshHelper.TextureType.COLORED_VERTICES_1D */ protected final Property<Function<Number, Number>> func = new SimpleObjectProperty<Function<Number, Number>>(t -> t) { @Override protected void invalidated() { super.invalidated(); if (model != null && model.getTextureType().equals(TriangleMeshHelper.TextureType.COLORED_VERTICES_1D)) { model.setFunction(func.getValue()); } } }; protected final Property<Boolean> invert = new SimpleBooleanProperty(this, "Invert Bump Map", false) { @Override protected void invalidated() { if (model != null && useBumpMap.getValue()) { if (model.getMaterial() != null && ((PhongMaterial) model.getMaterial()).getDiffuseMap() != null) { ((PhongMaterial) model.getMaterial()).setBumpMap( new NormalMap( bumpScale.doubleValue(), bumpFineScale.doubleValue(), invert.getValue(), ((PhongMaterial) model.getMaterial()).getDiffuseMap() ) ); } } } }; protected final DoubleProperty bumpScale = new SimpleDoubleProperty(this, "Bump Scale", 27d) { @Override protected void invalidated() { if (model != null) { if (model.getMaterial() != null && ((PhongMaterial) model.getMaterial()).getDiffuseMap() != null) { ((PhongMaterial) model.getMaterial()).setBumpMap( new NormalMap( bumpScale.doubleValue(), bumpFineScale.doubleValue(), invert.getValue(), ((PhongMaterial) model.getMaterial()).getDiffuseMap() ) ); } } } }; protected final ObjectProperty<Image> bumpMap = new SimpleObjectProperty<Image>(this, "bumpMap", null) { @Override protected void invalidated() { if (model != null) { } } }; protected final DoubleProperty bumpFineScale = new SimpleDoubleProperty(this, "Bump Fine Scale", 9d) { @Override protected void invalidated() { if (model != null) { if (model.getMaterial() != null && ((PhongMaterial) model.getMaterial()).getDiffuseMap() != null) { ((PhongMaterial) model.getMaterial()).setBumpMap( new NormalMap( bumpScale.doubleValue(), bumpFineScale.doubleValue(), invert.getValue(), ((PhongMaterial) model.getMaterial()).getDiffuseMap() ) ); } } } }; protected final BooleanProperty useBumpMap = new SimpleBooleanProperty(this, "Generate Bump Map", false) { @Override protected void invalidated() { if (get()) { if (model != null) { if (model.getMaterial() != null && ((PhongMaterial) model.getMaterial()).getDiffuseMap() != null) { ((PhongMaterial) model.getMaterial()).setBumpMap( new NormalMap( bumpScale.doubleValue(), bumpFineScale.doubleValue(), invert.getValue(), ((PhongMaterial) model.getMaterial()).getDiffuseMap() ) ); } } } else { if (model != null) { ((PhongMaterial) model.getMaterial()).setBumpMap(null); } } } }; protected final DoubleProperty specularPower = new SimpleDoubleProperty(this, "Specular Power") { @Override protected void invalidated() { if (model != null) { if (model.getMaterial() != null) { ((PhongMaterial) model.getMaterial()).setSpecularPower(specularPower.getValue()); } } } }; protected final ObjectProperty<Color> specColorBinding = new SimpleObjectProperty<Color>(Color.BLACK) { @Override protected void invalidated() { super.invalidated(); if (model != null) { material.setSpecularColor(get()); } } }; protected final IntegerProperty specColor = new SimpleIntegerProperty(this, "Specular Color", 1) { @Override protected void invalidated() { super.invalidated(); if (model != null) { specColorBinding.set(Color.hsb(360 * (1d - get() / 1530d), 1, 1)); } } }; }