Gltf: added support for PBR colored material
This commit is contained in:
parent
7951f5a987
commit
3bbfabed5e
@ -37,6 +37,7 @@ import com.jme3.light.PointLight;
|
|||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.plugins.gltf.GltfModelKey;
|
||||||
import com.jme3.scene.shape.Sphere;
|
import com.jme3.scene.shape.Sphere;
|
||||||
|
|
||||||
public class TestGltfLoading extends SimpleApplication {
|
public class TestGltfLoading extends SimpleApplication {
|
||||||
@ -67,8 +68,8 @@ public class TestGltfLoading extends SimpleApplication {
|
|||||||
PointLight pl1 = new PointLight(new Vector3f(-5.0f, -5.0f, -5.0f), ColorRGBA.White.mult(0.5f), 50);
|
PointLight pl1 = new PointLight(new Vector3f(-5.0f, -5.0f, -5.0f), ColorRGBA.White.mult(0.5f), 50);
|
||||||
rootNode.addLight(pl1);
|
rootNode.addLight(pl1);
|
||||||
|
|
||||||
//rootNode.attachChild(assetManager.loadModel("Models/gltf/box/box.gltf"));
|
rootNode.attachChild(assetManager.loadModel("Models/gltf/box/box.gltf"));
|
||||||
rootNode.attachChild(assetManager.loadModel("Models/gltf/duck/Duck.gltf"));
|
//rootNode.attachChild(assetManager.loadModel(new GltfModelKey("Models/gltf/duck/Duck.gltf")));
|
||||||
|
|
||||||
//rootNode.attachChild(assetManager.loadModel("Models/gltf/hornet/scene.gltf"));
|
//rootNode.attachChild(assetManager.loadModel("Models/gltf/hornet/scene.gltf"));
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,17 @@ import com.google.gson.*;
|
|||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.jme3.asset.*;
|
import com.jme3.asset.*;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue;
|
||||||
import com.jme3.scene.*;
|
import com.jme3.scene.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.Buffer;
|
import java.nio.Buffer;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static com.jme3.scene.plugins.gltf.GltfUtils.*;
|
import static com.jme3.scene.plugins.gltf.GltfUtils.*;
|
||||||
|
|
||||||
@ -20,6 +24,8 @@ import static com.jme3.scene.plugins.gltf.GltfUtils.*;
|
|||||||
*/
|
*/
|
||||||
public class GltfLoader implements AssetLoader {
|
public class GltfLoader implements AssetLoader {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(GltfLoader.class.getName());
|
||||||
|
|
||||||
//Data cache for already parsed JME objects
|
//Data cache for already parsed JME objects
|
||||||
private Map<String, Object[]> dataCache = new HashMap<>();
|
private Map<String, Object[]> dataCache = new HashMap<>();
|
||||||
private JsonArray scenes;
|
private JsonArray scenes;
|
||||||
@ -30,9 +36,14 @@ public class GltfLoader implements AssetLoader {
|
|||||||
private JsonArray buffers;
|
private JsonArray buffers;
|
||||||
private JsonArray materials;
|
private JsonArray materials;
|
||||||
private Material defaultMat;
|
private Material defaultMat;
|
||||||
private byte[] tmpByteArray;
|
|
||||||
private AssetInfo info;
|
private AssetInfo info;
|
||||||
|
|
||||||
|
private static Map<String, MaterialAdapter> defaultMaterialAdapters = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultMaterialAdapters.put("pbrMetallicRoughness", new PBRMaterialAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object load(AssetInfo assetInfo) throws IOException {
|
public Object load(AssetInfo assetInfo) throws IOException {
|
||||||
try {
|
try {
|
||||||
@ -46,7 +57,6 @@ public class GltfLoader implements AssetLoader {
|
|||||||
defaultMat.setFloat("Roughness", 1f);
|
defaultMat.setFloat("Roughness", 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JsonObject root = new JsonParser().parse(new JsonReader(new InputStreamReader(assetInfo.openStream()))).getAsJsonObject();
|
JsonObject root = new JsonParser().parse(new JsonReader(new InputStreamReader(assetInfo.openStream()))).getAsJsonObject();
|
||||||
|
|
||||||
JsonObject asset = root.getAsJsonObject().get("asset").getAsJsonObject();
|
JsonObject asset = root.getAsJsonObject().get("asset").getAsJsonObject();
|
||||||
@ -66,8 +76,6 @@ public class GltfLoader implements AssetLoader {
|
|||||||
buffers = root.getAsJsonArray("buffers");
|
buffers = root.getAsJsonArray("buffers");
|
||||||
materials = root.getAsJsonArray("materials");
|
materials = root.getAsJsonArray("materials");
|
||||||
|
|
||||||
allocatedTmpByteArray();
|
|
||||||
|
|
||||||
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
||||||
|
|
||||||
Node n = loadScenes(defaultScene);
|
Node n = loadScenes(defaultScene);
|
||||||
@ -85,21 +93,6 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void allocatedTmpByteArray() {
|
|
||||||
//Allocate the tmpByteArray to the biggest bufferView
|
|
||||||
if (bufferViews == null) {
|
|
||||||
throw new AssetLoadException("No buffer view defined but one is referenced by an accessor");
|
|
||||||
}
|
|
||||||
int maxLength = 0;
|
|
||||||
for (JsonElement bufferView : bufferViews) {
|
|
||||||
Integer byteLength = getAsInteger(bufferView.getAsJsonObject(), "byteLength");
|
|
||||||
if (byteLength != null && maxLength < byteLength) {
|
|
||||||
maxLength = byteLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmpByteArray = new byte[maxLength];
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isSupported(String version, String minVersion) {
|
private boolean isSupported(String version, String minVersion) {
|
||||||
return "2.0".equals(version);
|
return "2.0".equals(version);
|
||||||
}
|
}
|
||||||
@ -152,26 +145,19 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
||||||
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
||||||
Mesh[] primitives = loadMeshPrimitives(meshIndex);
|
Geometry[] primitives = loadMeshPrimitives(meshIndex);
|
||||||
if (primitives.length > 1) {
|
if (primitives.length > 1) {
|
||||||
//only one mesh, lets just make a geometry.
|
//only one geometry, let's not wrap it in another node.
|
||||||
Geometry geometry = new Geometry(null, primitives[0]);
|
spatial = primitives[0];
|
||||||
geometry.setMaterial(mat);
|
|
||||||
geometry.updateModelBound();
|
|
||||||
spatial = geometry;
|
|
||||||
} else {
|
} else {
|
||||||
//several meshes, let's make a parent Node and attach several geometries to it
|
//several geometries, let's make a parent Node and attach them to it
|
||||||
Node node = new Node();
|
Node node = new Node();
|
||||||
for (Mesh primitive : primitives) {
|
for (Geometry primitive : primitives) {
|
||||||
Geometry geom = new Geometry(null, primitive);
|
node.attachChild(primitive);
|
||||||
geom.setMaterial(mat);
|
|
||||||
geom.updateModelBound();
|
|
||||||
node.attachChild(geom);
|
|
||||||
}
|
}
|
||||||
spatial = node;
|
spatial = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
spatial.setName(loadMeshName(meshIndex));
|
spatial.setName(loadMeshName(meshIndex));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -235,10 +221,15 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mesh[] loadMeshPrimitives(int meshIndex) throws IOException {
|
private Geometry[] loadMeshPrimitives(int meshIndex) throws IOException {
|
||||||
Mesh[] meshArray = (Mesh[]) fetchFromCache("meshes", meshIndex, Object.class);
|
Geometry[] geomArray = (Geometry[]) fetchFromCache("meshes", meshIndex, Object.class);
|
||||||
if (meshArray != null) {
|
if (geomArray != null) {
|
||||||
return meshArray;
|
//cloning the geoms.
|
||||||
|
Geometry[] geoms = new Geometry[geomArray.length];
|
||||||
|
for (int i = 0; i < geoms.length; i++) {
|
||||||
|
geoms[i] = geomArray[i].clone(false);
|
||||||
|
}
|
||||||
|
return geoms;
|
||||||
}
|
}
|
||||||
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
||||||
JsonArray primitives = meshData.getAsJsonArray("primitives");
|
JsonArray primitives = meshData.getAsJsonArray("primitives");
|
||||||
@ -246,7 +237,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
throw new AssetLoadException("Can't find any primitives in mesh " + meshIndex);
|
throw new AssetLoadException("Can't find any primitives in mesh " + meshIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
meshArray = new Mesh[primitives.size()];
|
geomArray = new Geometry[primitives.size()];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (JsonElement primitive : primitives) {
|
for (JsonElement primitive : primitives) {
|
||||||
JsonObject meshObject = primitive.getAsJsonObject();
|
JsonObject meshObject = primitive.getAsJsonObject();
|
||||||
@ -263,14 +254,28 @@ public class GltfLoader implements AssetLoader {
|
|||||||
for (Map.Entry<String, JsonElement> entry : attributes.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : attributes.entrySet()) {
|
||||||
mesh.setBuffer(loadVertexBuffer(entry.getValue().getAsInt(), getVertexBufferType(entry.getKey())));
|
mesh.setBuffer(loadVertexBuffer(entry.getValue().getAsInt(), getVertexBufferType(entry.getKey())));
|
||||||
}
|
}
|
||||||
meshArray[index] = mesh;
|
Geometry geom = new Geometry(null, mesh);
|
||||||
|
|
||||||
|
Integer materialIndex = getAsInteger(meshObject, "material");
|
||||||
|
if (materialIndex == null) {
|
||||||
|
geom.setMaterial(defaultMat);
|
||||||
|
} else {
|
||||||
|
geom.setMaterial(loadMaterial(materialIndex));
|
||||||
|
if (geom.getMaterial().getAdditionalRenderState().getBlendMode() == RenderState.BlendMode.Alpha) {
|
||||||
|
//Alpha blending is on on this material let's place the geom in the transparent bucket
|
||||||
|
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
geom.updateModelBound();
|
||||||
|
geomArray[index] = geom;
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
//TODO material, targets(morph anim...)
|
//TODO material, targets(morph anim...)
|
||||||
}
|
}
|
||||||
|
|
||||||
addToCache("meshes", meshIndex, meshArray, meshes.size());
|
addToCache("meshes", meshIndex, geomArray, meshes.size());
|
||||||
return meshArray;
|
return geomArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private VertexBuffer loadVertexBuffer(int accessorIndex, VertexBuffer.Type bufferType) throws IOException {
|
private VertexBuffer loadVertexBuffer(int accessorIndex, VertexBuffer.Type bufferType) throws IOException {
|
||||||
@ -373,6 +378,46 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Material loadMaterial(int materialIndex) {
|
||||||
|
if (materials == null) {
|
||||||
|
throw new AssetLoadException("There is no material defined yet a mesh references one");
|
||||||
|
}
|
||||||
|
JsonObject matData = materials.get(materialIndex).getAsJsonObject();
|
||||||
|
JsonObject pbrMat = matData.getAsJsonObject("pbrMetallicRoughness");
|
||||||
|
|
||||||
|
if (pbrMat == null) {
|
||||||
|
logger.log(Level.WARNING, "Unable to find any pbrMetallicRoughness material entry in material " + materialIndex + ". Only PBR material is supported for now");
|
||||||
|
return defaultMat;
|
||||||
|
}
|
||||||
|
MaterialAdapter adapter = null;
|
||||||
|
if (info.getKey() instanceof GltfModelKey) {
|
||||||
|
adapter = ((GltfModelKey) info.getKey()).getAdapterForMaterial("pbrMetallicRoughness");
|
||||||
|
}
|
||||||
|
if (adapter == null) {
|
||||||
|
adapter = defaultMaterialAdapters.get("pbrMetallicRoughness");
|
||||||
|
}
|
||||||
|
|
||||||
|
Material mat = adapter.getMaterial(info.getManager());
|
||||||
|
mat.setName(getAsString(matData, "name"));
|
||||||
|
|
||||||
|
adapter.setParam(mat, "baseColorFactor", getAsColor(pbrMat, "baseColorFactor", ColorRGBA.White));
|
||||||
|
adapter.setParam(mat, "metallicFactor", getAsFloat(pbrMat, "metallicFactor", 1f));
|
||||||
|
adapter.setParam(mat, "roughnessFactor", getAsFloat(pbrMat, "roughnessFactor", 1f));
|
||||||
|
adapter.setParam(mat, "emissiveFactor", getAsColor(matData, "emissiveFactor", ColorRGBA.Black));
|
||||||
|
adapter.setParam(mat, "alphaMode", getAsString(matData, "alphaMode"));
|
||||||
|
adapter.setParam(mat, "alphaCutoff", getAsFloat(matData, "alphaCutoff"));
|
||||||
|
adapter.setParam(mat, "doubleSided", getAsBoolean(matData, "doubleSided"));
|
||||||
|
|
||||||
|
//TODO textures
|
||||||
|
//adapter.setParam(mat, "baseColorTexture", readTexture);
|
||||||
|
//adapter.setParam(mat, "metallicRoughnessTexture", readTexture);
|
||||||
|
//adapter.setParam(mat, "normalTexture", readTexture);
|
||||||
|
//adapter.setParam(mat, "occlusionTexture", readTexture);
|
||||||
|
//adapter.setParam(mat, "emissiveTexture", readTexture);
|
||||||
|
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
|
||||||
private String loadMeshName(int meshIndex) {
|
private String loadMeshName(int meshIndex) {
|
||||||
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
||||||
return getAsString(meshData, "name");
|
return getAsString(meshData, "name");
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.jme3.scene.plugins.gltf;
|
||||||
|
|
||||||
|
import com.jme3.asset.ModelKey;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Nehon on 08/08/2017.
|
||||||
|
*/
|
||||||
|
public class GltfModelKey extends ModelKey {
|
||||||
|
|
||||||
|
private Map<String, MaterialAdapter> materialAdapters = new HashMap<>();
|
||||||
|
|
||||||
|
public GltfModelKey(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GltfModelKey() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerMaterialAdapter(String gltfMaterialName, MaterialAdapter adapter) {
|
||||||
|
materialAdapters.put(gltfMaterialName, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialAdapter getAdapterForMaterial(String gltfMaterialName) {
|
||||||
|
return materialAdapters.get(gltfMaterialName);
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package com.jme3.scene.plugins.gltf;
|
package com.jme3.scene.plugins.gltf;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.*;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.jme3.asset.AssetLoadException;
|
import com.jme3.asset.AssetLoadException;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
import com.jme3.util.LittleEndien;
|
import com.jme3.util.LittleEndien;
|
||||||
@ -229,6 +229,16 @@ public class GltfUtils {
|
|||||||
return el == null ? defaultValue : el.getAsInt();
|
return el == null ? defaultValue : el.getAsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Float getAsFloat(JsonObject parent, String name) {
|
||||||
|
JsonElement el = parent.get(name);
|
||||||
|
return el == null ? null : el.getAsFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Float getAsFloat(JsonObject parent, String name, float defaultValue) {
|
||||||
|
JsonElement el = parent.get(name);
|
||||||
|
return el == null ? defaultValue : el.getAsFloat();
|
||||||
|
}
|
||||||
|
|
||||||
public static Boolean getAsBoolean(JsonObject parent, String name) {
|
public static Boolean getAsBoolean(JsonObject parent, String name) {
|
||||||
JsonElement el = parent.get(name);
|
JsonElement el = parent.get(name);
|
||||||
return el == null ? null : el.getAsBoolean();
|
return el == null ? null : el.getAsBoolean();
|
||||||
@ -239,6 +249,21 @@ public class GltfUtils {
|
|||||||
return el == null ? defaultValue : el.getAsBoolean();
|
return el == null ? defaultValue : el.getAsBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ColorRGBA getAsColor(JsonObject parent, String name) {
|
||||||
|
JsonElement el = parent.get(name);
|
||||||
|
if (el == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonArray color = el.getAsJsonArray();
|
||||||
|
return new ColorRGBA(color.get(0).getAsFloat(), color.get(1).getAsFloat(), color.get(2).getAsFloat(), color.get(3).getAsFloat());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColorRGBA getAsColor(JsonObject parent, String name, ColorRGBA defaultValue) {
|
||||||
|
ColorRGBA color = getAsColor(parent, name);
|
||||||
|
return color == null ? defaultValue : color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void assertNotNull(Object o, String errorMessage) {
|
public static void assertNotNull(Object o, String errorMessage) {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
throw new AssetLoadException(errorMessage);
|
throw new AssetLoadException(errorMessage);
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.jme3.scene.plugins.gltf;
|
||||||
|
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetLoadException;
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.material.*;
|
||||||
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.shader.VarType;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A MaterialAdapter allows to map a GLTF material to a JME material.
|
||||||
|
* It maps each gltf parameter to it's matching parameter in the JME material,
|
||||||
|
* and allows for some conversion if the JME material model doesn't exactly match the gltf material model
|
||||||
|
* Created by Nehon on 08/08/2017.
|
||||||
|
*/
|
||||||
|
public abstract class MaterialAdapter {
|
||||||
|
|
||||||
|
private Map<String, String> paramsMapping = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should return the material definition used by this material adapter
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected abstract String getMaterialDefPath();
|
||||||
|
|
||||||
|
protected abstract MatParam adaptMatParam(Material mat, MatParam param);
|
||||||
|
|
||||||
|
public Material getMaterial(AssetManager assetManager) {
|
||||||
|
return new Material(assetManager, getMaterialDefPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParam(Material mat, String gltfParamName, Object value) {
|
||||||
|
String name = getJmeParamName(gltfParamName);
|
||||||
|
if (name == null || value == null) {
|
||||||
|
//no mapping registered or value is null, let's ignore this param
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MatParam param;
|
||||||
|
if (value instanceof Texture) {
|
||||||
|
MatParam defParam = mat.getMaterialDef().getMaterialParam(name);
|
||||||
|
if (defParam == null) {
|
||||||
|
throw new AssetLoadException("Material definition " + getMaterialDefPath() + " has not param with name" + name);
|
||||||
|
}
|
||||||
|
if (!(defParam instanceof MatParamTexture)) {
|
||||||
|
throw new AssetLoadException("param with name" + name + "in material definition " + getMaterialDefPath() + " should be a texture param");
|
||||||
|
}
|
||||||
|
param = new MatParamTexture(VarType.Texture2D, name, (Texture) value, ((MatParamTexture) defParam).getColorSpace());
|
||||||
|
param = adaptMatParam(mat, param);
|
||||||
|
if (param != null) {
|
||||||
|
mat.setTextureParam(param.getName(), param.getVarType(), (Texture) param.getValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
param = new MatParam(getVarType(value), name, value);
|
||||||
|
param = adaptMatParam(mat, param);
|
||||||
|
if (param != null) {
|
||||||
|
mat.setParam(param.getName(), param.getVarType(), param.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addParamMapping(String gltfParamName, String jmeParamName) {
|
||||||
|
paramsMapping.put(gltfParamName, jmeParamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getJmeParamName(String gltfParamName) {
|
||||||
|
return paramsMapping.get(gltfParamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private VarType getVarType(Object value) {
|
||||||
|
if (value instanceof Float) return VarType.Float;
|
||||||
|
if (value instanceof Integer) return VarType.Int;
|
||||||
|
if (value instanceof Boolean) return VarType.Boolean;
|
||||||
|
if (value instanceof ColorRGBA) return VarType.Vector4;
|
||||||
|
if (value instanceof Vector4f) return VarType.Vector4;
|
||||||
|
if (value instanceof Vector3f) return VarType.Vector3;
|
||||||
|
if (value instanceof Vector2f) return VarType.Vector2;
|
||||||
|
if (value instanceof Matrix3f) return VarType.Matrix3;
|
||||||
|
if (value instanceof Matrix4f) return VarType.Matrix4;
|
||||||
|
throw new AssetLoadException("Unsupported material parameter type : " + value.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.jme3.scene.plugins.gltf;
|
||||||
|
|
||||||
|
import com.jme3.material.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Nehon on 08/08/2017.
|
||||||
|
*/
|
||||||
|
public class PBRMaterialAdapter extends MaterialAdapter {
|
||||||
|
|
||||||
|
|
||||||
|
public PBRMaterialAdapter() {
|
||||||
|
addParamMapping("baseColorFactor", "BaseColor");
|
||||||
|
addParamMapping("baseColorTexture", "BaseColorMap");
|
||||||
|
addParamMapping("metallicFactor", "Metallic");
|
||||||
|
addParamMapping("roughnessFactor", "Roughness");
|
||||||
|
addParamMapping("metallicRoughnessTexture", "MetallicRoughnessMap");
|
||||||
|
addParamMapping("normalTexture", "NormalMap");
|
||||||
|
addParamMapping("occlusionTexture", "LightMap");
|
||||||
|
addParamMapping("emisiveTexture", "EmissiveMap");
|
||||||
|
addParamMapping("emisiveFactor", "Emissive");
|
||||||
|
addParamMapping("alphaMode", "alpha");
|
||||||
|
addParamMapping("alphaCutoff", "AlphaDiscardThreshold");
|
||||||
|
addParamMapping("doubleSided", "doubleSided");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getMaterialDefPath() {
|
||||||
|
return "Common/MatDefs/Light/PBRLighting.j3md";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MatParam adaptMatParam(Material mat, MatParam param) {
|
||||||
|
if (param.getName().equals("alpha")) {
|
||||||
|
String alphaMode = (String) param.getValue();
|
||||||
|
switch (alphaMode) {
|
||||||
|
case "MASK":
|
||||||
|
case "BLEND":
|
||||||
|
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (param.getName().equals("doubleSided")) {
|
||||||
|
boolean doubleSided = (boolean) param.getValue();
|
||||||
|
if (doubleSided) {
|
||||||
|
//Note that this is not completely right as normals on the back side will be in the wrong direction.
|
||||||
|
mat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (param.getName().equals("MetallicRoughnessMap")) {
|
||||||
|
//use packed Metallic/Roughness
|
||||||
|
mat.setBoolean("UsePackedMR", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user