This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new 03badce557 feat(Material): separate material in dedicated subclasses
instead of a Map of properties
03badce557 is described below
commit 03badce5575d267216625f6c1bed700683044ca3
Author: jsorel <[email protected]>
AuthorDate: Thu Jul 23 22:12:12 2026 +0200
feat(Material): separate material in dedicated subclasses instead of a Map
of properties
---
.../org/apache/sis/geometries/scene/Material.java | 628 ---------------------
.../org/apache/sis/geometries/scene/Model.java | 1 +
.../org/apache/sis/geometries/scene/Surface.java | 4 +-
.../sis/geometries/scene/material/BlinnPhong.java | 198 +++++++
.../sis/geometries/scene/material/Material.java | 209 +++++++
.../apache/sis/geometries/scene/material/PBR.java | 342 +++++++++++
.../sis/geometries/scene/material/PBRSG.java | 203 +++++++
7 files changed, 956 insertions(+), 629 deletions(-)
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Material.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Material.java
deleted file mode 100644
index 88826b1df1..0000000000
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Material.java
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.sis.geometries.scene;
-
-import java.awt.Color;
-import java.util.HashMap;
-import java.util.Objects;
-import org.apache.sis.util.ArgumentChecks;
-
-
-/**
- * A material is a set of properties defining a visual representation.
- * Materials on there own do not suffice to obtain the visual aspect
- * of a model, they must be combined with a rendering technique.
- *
- * @author Johann Sorel (Geomatys)
- */
-public class Material extends HashMap<String,Object> {
-
- public static enum Technique {
- BLINN_PHONG,
- /**
- * Physically-Based Rendering
- */
- PBR,
- /**
- * Specular-glossiness material model from Physically-Based Rendering
(PBR)
- */
- PBRSG
- }
-
- public static final String ALPHA_MODE_OPAQUE = "OPAQUE";
- public static final String ALPHA_MODE_MASK = "MASK";
- public static final String ALPHA_MODE_BLEND = "BLEND";
-
- // PBR rendering technique
/////////////////////////////////////////////////
-
- /** Boolean, default is false */
- public static final String DOUBLESIDED = "doubleSided";
- /** Double, The alpha cutoff value of the material. default is 0.5 */
- public static final String ALPHACUTOFF = "alphaCutoff";
- /** String alpha mode. default is opaque*/
- public static final String ALPHAMODE = "alphaMode";
- /** Color */
- public static final String EMISSIVEFACTOR = "emissiveFactor";
- /** Texture */
- public static final String EMISSIVETEXTURE = "emissiveTexture";
- /** Texture */
- public static final String OCCLUSIONTEXTURE = "occlusionTexture";
- public static final String OCCLUSIONSTRENGTH = "occlusionStrength";
- /** Texture */
- public static final String NORMALTEXTURE = "normalTexture";
- public static final String NORMALSCALE = "normalScale";
-
-
- /** Color */
- public static final String PBR_BASECOLORFACTOR = "baseColorFactor";
- /** Texture */
- public static final String PBR_BASECOLORTEXTURE = "baseColorTexture";
- /** Number */
- public static final String PBR_METALLICFACTOR = "metallicFactor";
- /** Number */
- public static final String PBR_ROUGHNESSFACTOR = "roughnessFactor";
- /** Texture */
- public static final String PBR_METALLICROUGHNESSTEXTURE =
"metallicRoughnessTexture";
-
- // PBR rendering technique
/////////////////////////////////////////////////
-
- /** Color */
- public static final String PBRSG_DIFFUSEFACTOR = "diffuseFactor";
- /** Texture */
- public static final String PBRSG_DIFFUSETEXTURE = "diffuseTexture";
- /** Color */
- public static final String PBRSG_SPECULARFACTOR = "specularFactor";
- /** Scalar */
- public static final String PBRSG_GLOSSINESSFACTOR = "glossinessFactor";
- /** Texture */
- public static final String PBRSG_SPECULAR_GLOSSINESS_TEXTURE =
"specularGlossinessTexture";
-
-
- // Blinn-Phong rendering technique
/////////////////////////////////////////
-
- /** Color */
- public static final String BP_AMBIANTFACTOR = "ambiantFactor";
- /** Texture */
- public static final String BP_AMBIANTTEXTURE = "ambiantTexture";
- /** Color */
- public static final String BP_DIFFUSEFACTOR = "diffuseFactor";
- /** Texture */
- public static final String BP_DIFFUSETEXTURE = "diffuseTexture";
- /** Color */
- public static final String BP_SPECULARFACTOR = "specularFactor";
- /** Texture */
- public static final String BP_SPECULARTEXTURE = "specularTexture";
-
- // Unlit rendering technique /////////////////////////////////////////
- // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_unlit/README.md
-
- /** Boolean */
- public static final String LIGHTS_UNLIT = "unlit";
-
- // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md
- /** Double */
- public static final String IOR = "ior";
-
- // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md
- /** Double */
- public static final String TRANSMISSIONFACTOR = "transmissionFactor";
- /** Texture */
- public static final String TRANSMISSIONTEXTURE = "transmissionTexture";
-
- // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md
- /** Double */
- public static final String THICKNESSFACTOR = "thicknessFactor";
- /** Texture */
- public static final String THICKNESSTEXTURE = "thicknessTexture";
- /** Double */
- public static final String ATTENUATIONDISTANCE = "attenuationDistance";
- /** Color */
- public static final String ATTENUATIONCOLOR = "attenuationColor";
-
-
- private String id;
- private Technique technique = Technique.PBR;
-
- public Material() {
-
- }
-
- /**
- * @return material identifier
- */
- public String getIdentifier() {
- return id;
- }
-
- /**
- * @param id set material identifier
- */
- public void setIdentifier(String id) {
- this.id = id;
- }
-
- /**
- * Get material rendering technique.
- * Blinn-Phong and PBR are the most common.
- * @return technique, never null.
- */
- public Technique getTechnique() {
- return technique;
- }
-
- /**
- * @param technique rendering technique
- */
- public void setTechnique(Technique technique) {
- ArgumentChecks.ensureNonNull("technique", technique);
- this.technique = technique;
- }
-
- /**
- * Default is OPAQUE
- * @return alphaMode
- */
- public String getAlphaMode() {
- String str = (String) get(ALPHAMODE);
- return (str == null) ? ALPHA_MODE_OPAQUE : str;
- }
-
- /**
- * Default is OPAQUE
- * @param alphaMode
- */
- public void setAlphaMode(String alphaMode) {
- put(ALPHAMODE, alphaMode);
- }
-
- /**
- * Default value is 0.5
- * @return alpha cutoff
- */
- public double getAlphaCutoff() {
- Number ac = (Number) get(ALPHACUTOFF);
- return (ac == null) ? 0.5 : ac.doubleValue();
- }
-
- /**
- * Default value is 0.5
- * @param cutoff
- */
- public void setAlphaCutoff(double cutoff) {
- ArgumentChecks.ensureBetween("alpha cutoff", 0.0, 1.0, cutoff);
- put(ALPHACUTOFF, cutoff);
- }
-
- /**
- * Default value is false
- * @return double sided.
- */
- public boolean isDoubleSided() {
- return Boolean.TRUE.equals(get(DOUBLESIDED));
- }
-
- /**
- * Default value is false
- * @param doublesided
- */
- public void setDoubleSided(boolean doublesided) {
- put(DOUBLESIDED, doublesided);
- }
-
- /**
- * Default is BLACK (0,0,0)
- * @return emmisive factor
- */
- public Color getEmissiveFactor() {
- Color color = (Color) get(EMISSIVEFACTOR);
- return (color == null) ? Color.BLACK : color;
- }
-
- /**
- * Default is BLACK (0,0,0)
- * @param color emmisive factor
- */
- public void setEmissiveFactor(Color color) {
- put(EMISSIVEFACTOR, color);
- }
-
- public Texture getEmissiveTexture() {
- return (Texture) get(EMISSIVETEXTURE);
- }
-
- public void setEmissiveTexture(Texture texture) {
- put(EMISSIVETEXTURE, texture);
- }
-
- public Texture getOcclusionTexture() {
- return (Texture) get(OCCLUSIONTEXTURE);
- }
-
- public void setOcclusionTexture(Texture texture) {
- put(OCCLUSIONTEXTURE, texture);
- }
-
- /**
- * Default is 1.0
- * @return occlusion strength
- */
- public double getOcclusionStrength() {
- Number strength = (Number) get(OCCLUSIONSTRENGTH);
- return (strength == null) ? 1.0 : strength.doubleValue();
- }
-
- /**
- * Default is 1.0
- * @param strength occlusion strength between 0.0 and 1.0
- */
- public void setOcclusionStrength(double strength) {
- ArgumentChecks.ensureBetween("occlusion strength", 0.0, 1.0, strength);
- put(OCCLUSIONSTRENGTH, strength);
- }
-
- public Texture getNormalTexture() {
- return (Texture) get(NORMALTEXTURE);
- }
-
- public void setNormalTexture(Texture texture) {
- put(NORMALTEXTURE, texture);
- }
-
- /**
- * Default is 1.0
- * @return normal scale
- */
- public double getNormalScale() {
- Number scale = (Number) get(NORMALSCALE);
- return (scale == null) ? 1.0 : scale.doubleValue();
- }
-
- /**
- * Default is 1.0
- * @param scale normal scale
- */
- public void setNormalScale(double scale) {
- ArgumentChecks.ensureBetween("normal scale", 0.0, 1.0, scale);
- put(NORMALSCALE, scale);
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @return pbr base color factor
- */
- public Color getPBRBaseColorFactor() {
- Color color = (Color) get(PBR_BASECOLORFACTOR);
- return (color == null) ? Color.WHITE : color;
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @param color pbr base color factor
- */
- public void setPBRBaseColorFactor(Color color) {
- put(PBR_BASECOLORFACTOR, color);
- }
-
- public Texture getPBRBaseColorTexture() {
- return (Texture) get(PBR_BASECOLORTEXTURE);
- }
-
- public void setPBRBaseColorTexture(Texture texture) {
- put(PBR_BASECOLORTEXTURE, texture);
- }
-
- /**
- * Default is 1.0
- * @return between 0.0 and 1.0
- */
- public double getPBRMetallicFactor() {
- Number factor = (Number) get(PBR_METALLICFACTOR);
- return (factor == null) ? 1.0 : factor.doubleValue();
- }
-
- /**
- * Default is 1.0
- * @param factor between 0.0 and 1.0
- */
- public void setPBRMetallicFactor(double factor) {
- ArgumentChecks.ensureBetween("pbr metallic factor", 0.0, 1.0, factor);
- put(PBR_METALLICFACTOR, factor);
- }
-
- /**
- * Default is 1.0
- * @return between 0.0 and 1.0
- */
- public double getPBRRoughnessFactor() {
- Number roughness = (Number) get(PBR_ROUGHNESSFACTOR);
- return (roughness == null) ? 1.0 : roughness.doubleValue();
- }
-
- /**
- * Default is 1.0
- * @param roughness between 0.0 and 1.0
- */
- public void setPBRRoughnessFactor(double roughness) {
- ArgumentChecks.ensureBetween("PBR roughness factor", 0.0, 1.0,
roughness);
- put(PBR_ROUGHNESSFACTOR, roughness);
- }
-
- public Texture getPBRMetallicRoughnessTexture() {
- return (Texture) get(PBR_METALLICROUGHNESSTEXTURE);
- }
-
- public void setPBRMetallicRoughnessTexture(Texture texture) {
- put(PBR_METALLICROUGHNESSTEXTURE, texture);
- }
-
- /**
- * Default is WHITE (1,1,1,1)
- * @return diffuse factor
- */
- public Color getPBRSGDiffuseFactor() {
- Color color = (Color) get(PBRSG_DIFFUSEFACTOR);
- return (color == null) ? Color.WHITE : color;
- }
-
- /**
- * Default is WHITE (1,1,1,1)
- * @param color diffuse factor
- */
- public void setPBRSGDiffuseFactor(Color color) {
- put(PBRSG_DIFFUSEFACTOR, color);
- }
-
- /**
- * Default is null
- * @return diffuse texture
- */
- public Texture getPBRSGDiffuseTexture() {
- return (Texture) get(PBRSG_DIFFUSETEXTURE);
- }
-
- /**
- * Default is null
- * @param texture diffuse
- */
- public void setPBRSGDiffuseTexture(Texture texture) {
- put(PBRSG_DIFFUSETEXTURE, texture);
- }
-
- /**
- * Default is 1.0
- * @return between 0.0 and 1.0
- */
- public double getPBRSGGlossinessFactor() {
- Number factor = (Number) get(PBRSG_GLOSSINESSFACTOR);
- return (factor == null) ? 1.0 : factor.doubleValue();
- }
-
- /**
- * Default is 1.0
- * @param factor between 0.0 and 1.0
- */
- public void setPBRSGGlossinessFactor(double factor) {
- ArgumentChecks.ensureBetween("pbrsg glossiness factor", 0.0, 1.0,
factor);
- put(PBRSG_GLOSSINESSFACTOR, factor);
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @return specular factor
- */
- public Color getPBRSGSpecularFactor() {
- Color color = (Color) get(PBRSG_SPECULARFACTOR);
- return (color == null) ? Color.WHITE : color;
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @param color specular factor
- */
- public void setPBRSGSpecularFactor(Color color) {
- put(PBRSG_SPECULARFACTOR, color);
- }
-
- /**
- * Default is null
- * @return specular glossiness texture
- */
- public Texture getPBRSGSpecularGlossinessTexture() {
- return (Texture) get(PBRSG_SPECULAR_GLOSSINESS_TEXTURE);
- }
-
- /**
- * Default is null
- * @param texture specular glossiness
- */
- public void setPBRSGSpecularGlossinessTexture(Texture texture) {
- put(PBRSG_SPECULAR_GLOSSINESS_TEXTURE, texture);
- }
-
- /**
- * Default value is false
- * @return true if lights should be disabled for this material.
- */
- public boolean isUnlit() {
- return Boolean.TRUE.equals(get(LIGHTS_UNLIT));
- }
-
- /**
- * Default value is false
- * @param unlit if lights should be disabled for this material.
- */
- public void setUnlit(boolean unlit) {
- put(LIGHTS_UNLIT, unlit);
- }
-
- /**
- * Default value is 1.5
- * @return index of refraction
- */
- public double getIOR() {
- Number ac = (Number) get(IOR);
- return (ac == null) ? 1.5 : ac.doubleValue();
- }
-
- /**
- * Default value is 1.5
- * @param ior
- */
- public void setIOR(double ior) {
- ArgumentChecks.ensureBetween("ior", 1.0, 100.0, ior);
- put(IOR, ior);
- }
-
- /**
- * Default value is 0.0
- * @return transmission factor
- */
- public double getTransmissionFactor() {
- Number ac = (Number) get(TRANSMISSIONFACTOR);
- return (ac == null) ? 0.0 : ac.doubleValue();
- }
-
- /**
- * Default value is 0.0
- * @param tf
- */
- public void setTransmissionFactor(double tf) {
- put(TRANSMISSIONFACTOR, tf);
- }
-
- /**
- * Default is null
- * @return transmission texture
- */
- public Texture getTransmissionTexture() {
- return (Texture) get(TRANSMISSIONTEXTURE);
- }
-
- /**
- * Default is null
- * @param texture transmission
- */
- public void setTransmissionTexture(Texture texture) {
- put(TRANSMISSIONTEXTURE, texture);
- }
-
- /**
- * Default value is 0.0
- * @return thickness factor
- */
- public double getThicknessFactor() {
- Number ac = (Number) get(THICKNESSFACTOR);
- return (ac == null) ? 0.0 : ac.doubleValue();
- }
-
- /**
- * Default value is 0.0
- * @param tf
- */
- public void setThicknessFactor(double tf) {
- put(THICKNESSFACTOR, tf);
- }
-
- /**
- * Default is null
- * @return thickness texture
- */
- public Texture getThicknessTexture() {
- return (Texture) get(THICKNESSTEXTURE);
- }
-
- /**
- * Default is null
- * @param texture thickness
- */
- public void setThicknessTexture(Texture texture) {
- put(THICKNESSTEXTURE, texture);
- }
-
- /**
- * Default value is +Infinity
- * @return volume attenuation distance
- */
- public double getAttenuationDistance() {
- Number ac = (Number) get(ATTENUATIONDISTANCE);
- return (ac == null) ? Double.POSITIVE_INFINITY : ac.doubleValue();
- }
-
- /**
- * Default value is +Infinity
- * @param ad volume attenuation distance
- */
- public void setAttenuationDistance(double ad) {
- put(ATTENUATIONDISTANCE, ad);
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @return volume attenuation color
- */
- public Color getAttenuationColor() {
- Color color = (Color) get(ATTENUATIONCOLOR);
- return (color == null) ? Color.WHITE : color;
- }
-
- /**
- * Default is WHITE (1,1,1)
- * @param color volume attenuation color
- */
- public void setAttenuationColor(Color color) {
- put(ATTENUATIONCOLOR, color);
- }
-
- public final class Matte extends Material {
- //todo separate parameters to different type of materials
- }
-
- public final class BlinnPhong extends Material {
- //todo separate parameters to different type of materials
- }
-
- public final class PhysicallyBased extends Material {
- //todo separate parameters to different type of materials
- }
-
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 83 * hash + Objects.hashCode(this.id);
- return hash;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final Material other = (Material) obj;
- if (!Objects.equals(this.id, other.id)) {
- return false;
- }
- return super.equals(obj);
- }
-
-}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Model.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Model.java
index 8a39c49b27..b49c4050ef 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Model.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Model.java
@@ -16,6 +16,7 @@
*/
package org.apache.sis.geometries.scene;
+import org.apache.sis.geometries.scene.material.Material;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
index 013b72c6cc..3e25e8e44e 100644
---
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/Surface.java
@@ -16,6 +16,8 @@
*/
package org.apache.sis.geometries.scene;
+import org.apache.sis.geometries.scene.material.PBR;
+import org.apache.sis.geometries.scene.material.Material;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -38,7 +40,7 @@ public class Surface {
public Surface(Geometry geometry) {
ArgumentChecks.ensureNonNull("geometry", geometry);
this.geometry = geometry;
- this.material = new Material();
+ this.material = new PBR();
}
public Surface(Geometry geometry, Material material) {
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/BlinnPhong.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/BlinnPhong.java
new file mode 100644
index 0000000000..1b25c2fbc5
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/BlinnPhong.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.geometries.scene.material;
+
+import java.awt.Color;
+import java.util.Objects;
+import org.apache.sis.geometries.scene.Texture;
+
+
+/**
+ * Blinn-Phong material, the classic ambient/diffuse/specular shading model.
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class BlinnPhong extends Material {
+
+ private Color ambientFactor = Color.BLACK;
+ private Texture ambientTexture;
+ private Color diffuseFactor = Color.WHITE;
+ private Texture diffuseTexture;
+ private Color specularFactor = Color.WHITE;
+ private Texture specularTexture;
+
+ public BlinnPhong() {
+ }
+
+ /**
+ * Default is BLACK (0,0,0)
+ * @return ambient factor
+ */
+ public Color getAmbientFactor() {
+ return ambientFactor;
+ }
+
+ /**
+ * Default is BLACK (0,0,0)
+ * @param color ambient factor
+ */
+ public void setAmbientFactor(Color color) {
+ this.ambientFactor = color;
+ }
+
+ public Texture getAmbientTexture() {
+ return ambientTexture;
+ }
+
+ public void setAmbientTexture(Texture texture) {
+ this.ambientTexture = texture;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @return diffuse factor
+ */
+ public Color getDiffuseFactor() {
+ return diffuseFactor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @param color diffuse factor
+ */
+ public void setDiffuseFactor(Color color) {
+ this.diffuseFactor = color;
+ }
+
+ public Texture getDiffuseTexture() {
+ return diffuseTexture;
+ }
+
+ public void setDiffuseTexture(Texture texture) {
+ this.diffuseTexture = texture;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @return specular factor
+ */
+ public Color getSpecularFactor() {
+ return specularFactor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @param color specular factor
+ */
+ public void setSpecularFactor(Color color) {
+ this.specularFactor = color;
+ }
+
+ public Texture getSpecularTexture() {
+ return specularTexture;
+ }
+
+ public void setSpecularTexture(Texture texture) {
+ this.specularTexture = texture;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 37 * hash + Objects.hashCode(getIdentifier());
+ hash = 37 * hash + Boolean.hashCode(isDoubleSided());
+ hash = 37 * hash + Objects.hashCode(getAlphaMode());
+ hash = 37 * hash + Double.hashCode(getAlphaCutoff());
+ hash = 37 * hash + Objects.hashCode(getEmissiveFactor());
+ hash = 37 * hash + Objects.hashCode(getEmissiveTexture());
+ hash = 37 * hash + Objects.hashCode(getOcclusionTexture());
+ hash = 37 * hash + Double.hashCode(getOcclusionStrength());
+ hash = 37 * hash + Objects.hashCode(getNormalTexture());
+ hash = 37 * hash + Double.hashCode(getNormalScale());
+ hash = 37 * hash + Boolean.hashCode(isUnlit());
+ hash = 37 * hash + Objects.hashCode(this.ambientFactor);
+ hash = 37 * hash + Objects.hashCode(this.ambientTexture);
+ hash = 37 * hash + Objects.hashCode(this.diffuseFactor);
+ hash = 37 * hash + Objects.hashCode(this.diffuseTexture);
+ hash = 37 * hash + Objects.hashCode(this.specularFactor);
+ hash = 37 * hash + Objects.hashCode(this.specularTexture);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final BlinnPhong other = (BlinnPhong) obj;
+ if (Double.compare(this.getAlphaCutoff(), other.getAlphaCutoff()) !=
0) {
+ return false;
+ }
+ if (Double.compare(this.getOcclusionStrength(),
other.getOcclusionStrength()) != 0) {
+ return false;
+ }
+ if (Double.compare(this.getNormalScale(), other.getNormalScale()) !=
0) {
+ return false;
+ }
+ if (this.isDoubleSided() != other.isDoubleSided()) {
+ return false;
+ }
+ if (this.isUnlit() != other.isUnlit()) {
+ return false;
+ }
+ if (!Objects.equals(this.getIdentifier(), other.getIdentifier())) {
+ return false;
+ }
+ if (!Objects.equals(this.getAlphaMode(), other.getAlphaMode())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveFactor(),
other.getEmissiveFactor())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveTexture(),
other.getEmissiveTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getOcclusionTexture(),
other.getOcclusionTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getNormalTexture(),
other.getNormalTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.ambientFactor, other.ambientFactor)) {
+ return false;
+ }
+ if (!Objects.equals(this.ambientTexture, other.ambientTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.diffuseFactor, other.diffuseFactor)) {
+ return false;
+ }
+ if (!Objects.equals(this.diffuseTexture, other.diffuseTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.specularFactor, other.specularFactor)) {
+ return false;
+ }
+ return Objects.equals(this.specularTexture, other.specularTexture);
+ }
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/Material.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/Material.java
new file mode 100644
index 0000000000..443ac5c8e0
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/Material.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.geometries.scene.material;
+
+import java.awt.Color;
+import org.apache.sis.geometries.scene.Texture;
+import org.apache.sis.util.ArgumentChecks;
+
+
+/**
+ * A material is a set of properties defining a visual representation.
+ * Materials on there own do not suffice to obtain the visual aspect
+ * of a model, they must be combined with a rendering technique.
+ *
+ * This base class holds the properties common to all shading techniques,
+ * regardless of the shading model used. See {@link BlinnPhong}, {@link PBR}
+ * and {@link PBRSG} for the technique-specific properties.
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public abstract sealed class Material permits BlinnPhong, PBR, PBRSG {
+
+ public static final String ALPHA_MODE_OPAQUE = "OPAQUE";
+ public static final String ALPHA_MODE_MASK = "MASK";
+ public static final String ALPHA_MODE_BLEND = "BLEND";
+
+ private String id;
+ private boolean doubleSided;
+ private String alphaMode = ALPHA_MODE_OPAQUE;
+ private double alphaCutoff = 0.5;
+ private Color emissiveFactor = Color.BLACK;
+ private Texture emissiveTexture;
+ private Texture occlusionTexture;
+ private double occlusionStrength = 1.0;
+ private Texture normalTexture;
+ private double normalScale = 1.0;
+ private boolean unlit;
+
+ Material() {
+ }
+
+ /**
+ * @return material identifier
+ */
+ public String getIdentifier() {
+ return id;
+ }
+
+ /**
+ * @param id set material identifier
+ */
+ public void setIdentifier(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Default is OPAQUE
+ * @return alphaMode
+ */
+ public String getAlphaMode() {
+ return alphaMode;
+ }
+
+ /**
+ * Default is OPAQUE
+ * @param alphaMode
+ */
+ public void setAlphaMode(String alphaMode) {
+ this.alphaMode = alphaMode;
+ }
+
+ /**
+ * Default value is 0.5
+ * @return alpha cutoff
+ */
+ public double getAlphaCutoff() {
+ return alphaCutoff;
+ }
+
+ /**
+ * Default value is 0.5
+ * @param cutoff
+ */
+ public void setAlphaCutoff(double cutoff) {
+ ArgumentChecks.ensureBetween("alpha cutoff", 0.0, 1.0, cutoff);
+ this.alphaCutoff = cutoff;
+ }
+
+ /**
+ * Default value is false
+ * @return double sided.
+ */
+ public boolean isDoubleSided() {
+ return doubleSided;
+ }
+
+ /**
+ * Default value is false
+ * @param doublesided
+ */
+ public void setDoubleSided(boolean doublesided) {
+ this.doubleSided = doublesided;
+ }
+
+ /**
+ * Default is BLACK (0,0,0)
+ * @return emmisive factor
+ */
+ public Color getEmissiveFactor() {
+ return emissiveFactor;
+ }
+
+ /**
+ * Default is BLACK (0,0,0)
+ * @param color emmisive factor
+ */
+ public void setEmissiveFactor(Color color) {
+ this.emissiveFactor = color;
+ }
+
+ public Texture getEmissiveTexture() {
+ return emissiveTexture;
+ }
+
+ public void setEmissiveTexture(Texture texture) {
+ this.emissiveTexture = texture;
+ }
+
+ public Texture getOcclusionTexture() {
+ return occlusionTexture;
+ }
+
+ public void setOcclusionTexture(Texture texture) {
+ this.occlusionTexture = texture;
+ }
+
+ /**
+ * Default is 1.0
+ * @return occlusion strength
+ */
+ public double getOcclusionStrength() {
+ return occlusionStrength;
+ }
+
+ /**
+ * Default is 1.0
+ * @param strength occlusion strength between 0.0 and 1.0
+ */
+ public void setOcclusionStrength(double strength) {
+ ArgumentChecks.ensureBetween("occlusion strength", 0.0, 1.0, strength);
+ this.occlusionStrength = strength;
+ }
+
+ public Texture getNormalTexture() {
+ return normalTexture;
+ }
+
+ public void setNormalTexture(Texture texture) {
+ this.normalTexture = texture;
+ }
+
+ /**
+ * Default is 1.0
+ * @return normal scale
+ */
+ public double getNormalScale() {
+ return normalScale;
+ }
+
+ /**
+ * Default is 1.0
+ * @param scale normal scale
+ */
+ public void setNormalScale(double scale) {
+ ArgumentChecks.ensureBetween("normal scale", 0.0, 1.0, scale);
+ this.normalScale = scale;
+ }
+
+ /**
+ * Default value is false
+ * @return true if lights should be disabled for this material.
+ */
+ public boolean isUnlit() {
+ return unlit;
+ }
+
+ /**
+ * Default value is false
+ * @param unlit if lights should be disabled for this material.
+ */
+ public void setUnlit(boolean unlit) {
+ this.unlit = unlit;
+ }
+
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBR.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBR.java
new file mode 100644
index 0000000000..d26cde3c81
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBR.java
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.geometries.scene.material;
+
+import java.awt.Color;
+import java.util.Objects;
+import org.apache.sis.geometries.scene.Texture;
+import org.apache.sis.util.ArgumentChecks;
+
+
+/**
+ * Physically-Based Rendering material using the metallic-roughness workflow.
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class PBR extends Material {
+
+ private Color baseColorFactor = Color.WHITE;
+ private Texture baseColorTexture;
+ private double metallicFactor = 1.0;
+ private double roughnessFactor = 1.0;
+ private Texture metallicRoughnessTexture;
+
+ // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_ior/README.md
+ private double ior = 1.5;
+
+ // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_transmission/README.md
+ private double transmissionFactor = 0.0;
+ private Texture transmissionTexture;
+
+ // See
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_volume/README.md
+ private double thicknessFactor = 0.0;
+ private Texture thicknessTexture;
+ private double attenuationDistance = Double.POSITIVE_INFINITY;
+ private Color attenuationColor = Color.WHITE;
+
+ public PBR() {
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @return pbr base color factor
+ */
+ public Color getBaseColorFactor() {
+ return baseColorFactor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @param color pbr base color factor
+ */
+ public void setBaseColorFactor(Color color) {
+ this.baseColorFactor = color;
+ }
+
+ public Texture getBaseColorTexture() {
+ return baseColorTexture;
+ }
+
+ public void setBaseColorTexture(Texture texture) {
+ this.baseColorTexture = texture;
+ }
+
+ /**
+ * Default is 1.0
+ * @return between 0.0 and 1.0
+ */
+ public double getMetallicFactor() {
+ return metallicFactor;
+ }
+
+ /**
+ * Default is 1.0
+ * @param factor between 0.0 and 1.0
+ */
+ public void setMetallicFactor(double factor) {
+ ArgumentChecks.ensureBetween("pbr metallic factor", 0.0, 1.0, factor);
+ this.metallicFactor = factor;
+ }
+
+ /**
+ * Default is 1.0
+ * @return between 0.0 and 1.0
+ */
+ public double getRoughnessFactor() {
+ return roughnessFactor;
+ }
+
+ /**
+ * Default is 1.0
+ * @param roughness between 0.0 and 1.0
+ */
+ public void setRoughnessFactor(double roughness) {
+ ArgumentChecks.ensureBetween("PBR roughness factor", 0.0, 1.0,
roughness);
+ this.roughnessFactor = roughness;
+ }
+
+ public Texture getMetallicRoughnessTexture() {
+ return metallicRoughnessTexture;
+ }
+
+ public void setMetallicRoughnessTexture(Texture texture) {
+ this.metallicRoughnessTexture = texture;
+ }
+
+ /**
+ * Default value is 1.5
+ * @return index of refraction
+ */
+ public double getIOR() {
+ return ior;
+ }
+
+ /**
+ * Default value is 1.5
+ * @param ior
+ */
+ public void setIOR(double ior) {
+ ArgumentChecks.ensureBetween("ior", 1.0, 100.0, ior);
+ this.ior = ior;
+ }
+
+ /**
+ * Default value is 0.0
+ * @return transmission factor
+ */
+ public double getTransmissionFactor() {
+ return transmissionFactor;
+ }
+
+ /**
+ * Default value is 0.0
+ * @param tf
+ */
+ public void setTransmissionFactor(double tf) {
+ this.transmissionFactor = tf;
+ }
+
+ /**
+ * Default is null
+ * @return transmission texture
+ */
+ public Texture getTransmissionTexture() {
+ return transmissionTexture;
+ }
+
+ /**
+ * Default is null
+ * @param texture transmission
+ */
+ public void setTransmissionTexture(Texture texture) {
+ this.transmissionTexture = texture;
+ }
+
+ /**
+ * Default value is 0.0
+ * @return thickness factor
+ */
+ public double getThicknessFactor() {
+ return thicknessFactor;
+ }
+
+ /**
+ * Default value is 0.0
+ * @param tf
+ */
+ public void setThicknessFactor(double tf) {
+ this.thicknessFactor = tf;
+ }
+
+ /**
+ * Default is null
+ * @return thickness texture
+ */
+ public Texture getThicknessTexture() {
+ return thicknessTexture;
+ }
+
+ /**
+ * Default is null
+ * @param texture thickness
+ */
+ public void setThicknessTexture(Texture texture) {
+ this.thicknessTexture = texture;
+ }
+
+ /**
+ * Default value is +Infinity
+ * @return volume attenuation distance
+ */
+ public double getAttenuationDistance() {
+ return attenuationDistance;
+ }
+
+ /**
+ * Default value is +Infinity
+ * @param ad volume attenuation distance
+ */
+ public void setAttenuationDistance(double ad) {
+ this.attenuationDistance = ad;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @return volume attenuation color
+ */
+ public Color getAttenuationColor() {
+ return attenuationColor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @param color volume attenuation color
+ */
+ public void setAttenuationColor(Color color) {
+ this.attenuationColor = color;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 41 * hash + Objects.hashCode(getIdentifier());
+ hash = 41 * hash + Boolean.hashCode(isDoubleSided());
+ hash = 41 * hash + Objects.hashCode(getAlphaMode());
+ hash = 41 * hash + Double.hashCode(getAlphaCutoff());
+ hash = 41 * hash + Objects.hashCode(getEmissiveFactor());
+ hash = 41 * hash + Objects.hashCode(getEmissiveTexture());
+ hash = 41 * hash + Objects.hashCode(getOcclusionTexture());
+ hash = 41 * hash + Double.hashCode(getOcclusionStrength());
+ hash = 41 * hash + Objects.hashCode(getNormalTexture());
+ hash = 41 * hash + Double.hashCode(getNormalScale());
+ hash = 41 * hash + Boolean.hashCode(isUnlit());
+ hash = 41 * hash + Objects.hashCode(this.baseColorFactor);
+ hash = 41 * hash + Objects.hashCode(this.baseColorTexture);
+ hash = 41 * hash + Double.hashCode(this.metallicFactor);
+ hash = 41 * hash + Double.hashCode(this.roughnessFactor);
+ hash = 41 * hash + Objects.hashCode(this.metallicRoughnessTexture);
+ hash = 41 * hash + Double.hashCode(this.ior);
+ hash = 41 * hash + Double.hashCode(this.transmissionFactor);
+ hash = 41 * hash + Objects.hashCode(this.transmissionTexture);
+ hash = 41 * hash + Double.hashCode(this.thicknessFactor);
+ hash = 41 * hash + Objects.hashCode(this.thicknessTexture);
+ hash = 41 * hash + Double.hashCode(this.attenuationDistance);
+ hash = 41 * hash + Objects.hashCode(this.attenuationColor);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final PBR other = (PBR) obj;
+ if (Double.compare(this.getAlphaCutoff(), other.getAlphaCutoff()) !=
0) {
+ return false;
+ }
+ if (Double.compare(this.getOcclusionStrength(),
other.getOcclusionStrength()) != 0) {
+ return false;
+ }
+ if (Double.compare(this.getNormalScale(), other.getNormalScale()) !=
0) {
+ return false;
+ }
+ if (this.isDoubleSided() != other.isDoubleSided()) {
+ return false;
+ }
+ if (this.isUnlit() != other.isUnlit()) {
+ return false;
+ }
+ if (Double.compare(this.metallicFactor, other.metallicFactor) != 0) {
+ return false;
+ }
+ if (Double.compare(this.roughnessFactor, other.roughnessFactor) != 0) {
+ return false;
+ }
+ if (Double.compare(this.ior, other.ior) != 0) {
+ return false;
+ }
+ if (Double.compare(this.transmissionFactor, other.transmissionFactor)
!= 0) {
+ return false;
+ }
+ if (Double.compare(this.thicknessFactor, other.thicknessFactor) != 0) {
+ return false;
+ }
+ if (Double.compare(this.attenuationDistance,
other.attenuationDistance) != 0) {
+ return false;
+ }
+ if (!Objects.equals(this.getIdentifier(), other.getIdentifier())) {
+ return false;
+ }
+ if (!Objects.equals(this.getAlphaMode(), other.getAlphaMode())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveFactor(),
other.getEmissiveFactor())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveTexture(),
other.getEmissiveTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getOcclusionTexture(),
other.getOcclusionTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getNormalTexture(),
other.getNormalTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.baseColorFactor, other.baseColorFactor)) {
+ return false;
+ }
+ if (!Objects.equals(this.baseColorTexture, other.baseColorTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.metallicRoughnessTexture,
other.metallicRoughnessTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.transmissionTexture,
other.transmissionTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.thicknessTexture, other.thicknessTexture)) {
+ return false;
+ }
+ return Objects.equals(this.attenuationColor, other.attenuationColor);
+ }
+}
diff --git
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBRSG.java
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBRSG.java
new file mode 100644
index 0000000000..6dec15207d
--- /dev/null
+++
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/scene/material/PBRSG.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.geometries.scene.material;
+
+import java.awt.Color;
+import java.util.Objects;
+import org.apache.sis.geometries.scene.Texture;
+import org.apache.sis.util.ArgumentChecks;
+
+
+/**
+ * Specular-glossiness material model from Physically-Based Rendering (PBR).
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class PBRSG extends Material {
+
+ private Color diffuseFactor = Color.WHITE;
+ private Texture diffuseTexture;
+ private Color specularFactor = Color.WHITE;
+ private double glossinessFactor = 1.0;
+ private Texture specularGlossinessTexture;
+
+ public PBRSG() {
+ }
+
+ /**
+ * Default is WHITE (1,1,1,1)
+ * @return diffuse factor
+ */
+ public Color getDiffuseFactor() {
+ return diffuseFactor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1,1)
+ * @param color diffuse factor
+ */
+ public void setDiffuseFactor(Color color) {
+ this.diffuseFactor = color;
+ }
+
+ /**
+ * Default is null
+ * @return diffuse texture
+ */
+ public Texture getDiffuseTexture() {
+ return diffuseTexture;
+ }
+
+ /**
+ * Default is null
+ * @param texture diffuse
+ */
+ public void setDiffuseTexture(Texture texture) {
+ this.diffuseTexture = texture;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @return specular factor
+ */
+ public Color getSpecularFactor() {
+ return specularFactor;
+ }
+
+ /**
+ * Default is WHITE (1,1,1)
+ * @param color specular factor
+ */
+ public void setSpecularFactor(Color color) {
+ this.specularFactor = color;
+ }
+
+ /**
+ * Default is 1.0
+ * @return between 0.0 and 1.0
+ */
+ public double getGlossinessFactor() {
+ return glossinessFactor;
+ }
+
+ /**
+ * Default is 1.0
+ * @param factor between 0.0 and 1.0
+ */
+ public void setGlossinessFactor(double factor) {
+ ArgumentChecks.ensureBetween("pbrsg glossiness factor", 0.0, 1.0,
factor);
+ this.glossinessFactor = factor;
+ }
+
+ /**
+ * Default is null
+ * @return specular glossiness texture
+ */
+ public Texture getSpecularGlossinessTexture() {
+ return specularGlossinessTexture;
+ }
+
+ /**
+ * Default is null
+ * @param texture specular glossiness
+ */
+ public void setSpecularGlossinessTexture(Texture texture) {
+ this.specularGlossinessTexture = texture;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 43 * hash + Objects.hashCode(getIdentifier());
+ hash = 43 * hash + Boolean.hashCode(isDoubleSided());
+ hash = 43 * hash + Objects.hashCode(getAlphaMode());
+ hash = 43 * hash + Double.hashCode(getAlphaCutoff());
+ hash = 43 * hash + Objects.hashCode(getEmissiveFactor());
+ hash = 43 * hash + Objects.hashCode(getEmissiveTexture());
+ hash = 43 * hash + Objects.hashCode(getOcclusionTexture());
+ hash = 43 * hash + Double.hashCode(getOcclusionStrength());
+ hash = 43 * hash + Objects.hashCode(getNormalTexture());
+ hash = 43 * hash + Double.hashCode(getNormalScale());
+ hash = 43 * hash + Boolean.hashCode(isUnlit());
+ hash = 43 * hash + Objects.hashCode(this.diffuseFactor);
+ hash = 43 * hash + Objects.hashCode(this.diffuseTexture);
+ hash = 43 * hash + Objects.hashCode(this.specularFactor);
+ hash = 43 * hash + Double.hashCode(this.glossinessFactor);
+ hash = 43 * hash + Objects.hashCode(this.specularGlossinessTexture);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final PBRSG other = (PBRSG) obj;
+ if (Double.compare(this.getAlphaCutoff(), other.getAlphaCutoff()) !=
0) {
+ return false;
+ }
+ if (Double.compare(this.getOcclusionStrength(),
other.getOcclusionStrength()) != 0) {
+ return false;
+ }
+ if (Double.compare(this.getNormalScale(), other.getNormalScale()) !=
0) {
+ return false;
+ }
+ if (this.isDoubleSided() != other.isDoubleSided()) {
+ return false;
+ }
+ if (this.isUnlit() != other.isUnlit()) {
+ return false;
+ }
+ if (Double.compare(this.glossinessFactor, other.glossinessFactor) !=
0) {
+ return false;
+ }
+ if (!Objects.equals(this.getIdentifier(), other.getIdentifier())) {
+ return false;
+ }
+ if (!Objects.equals(this.getAlphaMode(), other.getAlphaMode())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveFactor(),
other.getEmissiveFactor())) {
+ return false;
+ }
+ if (!Objects.equals(this.getEmissiveTexture(),
other.getEmissiveTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getOcclusionTexture(),
other.getOcclusionTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.getNormalTexture(),
other.getNormalTexture())) {
+ return false;
+ }
+ if (!Objects.equals(this.diffuseFactor, other.diffuseFactor)) {
+ return false;
+ }
+ if (!Objects.equals(this.diffuseTexture, other.diffuseTexture)) {
+ return false;
+ }
+ if (!Objects.equals(this.specularFactor, other.specularFactor)) {
+ return false;
+ }
+ return Objects.equals(this.specularGlossinessTexture,
other.specularGlossinessTexture);
+ }
+}