Allow model jsons to override the material library used by OBJ models.

Fix model loader test mod resources.
Update licenses.
This commit is contained in:
David Quintana 2020-01-01 17:15:49 +01:00
parent 53747b0cb5
commit ecb56054bc
5 changed files with 75 additions and 23 deletions

View file

@ -26,11 +26,17 @@ import net.minecraft.client.renderer.Vector4f;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException;
public class MaterialLibrary public class MaterialLibrary
{ {
public static final MaterialLibrary EMPTY = new MaterialLibrary();
final Map<String, Material> materials = Maps.newHashMap(); final Map<String, Material> materials = Maps.newHashMap();
private MaterialLibrary()
{
}
public MaterialLibrary(OBJLoader.LineReader reader) throws IOException public MaterialLibrary(OBJLoader.LineReader reader) throws IOException
{ {
Material currentMaterial = null; Material currentMaterial = null;
@ -97,10 +103,12 @@ public class MaterialLibrary
public Material getMaterial(String mat) public Material getMaterial(String mat)
{ {
if (!materials.containsKey(mat))
throw new NoSuchElementException("The material was not found in the library: " + mat);
return materials.get(mat); return materials.get(mat);
} }
public class Material public static class Material
{ {
public final String name; public final String name;
public Vector4f ambientColor = new Vector4f(0,0,0,1); public Vector4f ambientColor = new Vector4f(0,0,0,1);

View file

@ -67,17 +67,19 @@ public class OBJLoader implements IModelLoader<OBJModel>
boolean diffuseLighting = JSONUtils.getBoolean(modelContents, "diffuseLighting", false); boolean diffuseLighting = JSONUtils.getBoolean(modelContents, "diffuseLighting", false);
boolean flipV = JSONUtils.getBoolean(modelContents, "flip-v", false); boolean flipV = JSONUtils.getBoolean(modelContents, "flip-v", false);
boolean ambientToFullbright = JSONUtils.getBoolean(modelContents, "ambientToFullbright", true); boolean ambientToFullbright = JSONUtils.getBoolean(modelContents, "ambientToFullbright", true);
@Nullable
String materialLibraryOverrideLocation = modelContents.has("materialLibraryOverride") ? JSONUtils.getString(modelContents, "materialLibraryOverride") : null;
return loadModel(new ResourceLocation(modelLocation), detectCullableFaces, diffuseLighting, flipV, ambientToFullbright); return loadModel(new ModelSettings(new ResourceLocation(modelLocation), detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation));
} }
public OBJModel loadModel(ResourceLocation modelLocation, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright) public OBJModel loadModel(ModelSettings settings)
{ {
return modelCache.computeIfAbsent(new ModelSettings(modelLocation, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright), (data) -> { return modelCache.computeIfAbsent(settings, (data) -> {
IResource resource; IResource resource;
try try
{ {
resource = manager.getResource(modelLocation); resource = manager.getResource(settings.modelLocation);
} }
catch (IOException e) catch (IOException e)
{ {
@ -86,7 +88,7 @@ public class OBJLoader implements IModelLoader<OBJModel>
try(LineReader rdr = new LineReader(resource)) try(LineReader rdr = new LineReader(resource))
{ {
return new OBJModel(modelLocation, rdr, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright); return new OBJModel(rdr, settings);
} }
catch (Exception e) catch (Exception e)
{ {
@ -133,6 +135,7 @@ public class OBJLoader implements IModelLoader<OBJModel>
@Nullable @Nullable
public String[] readAndSplitLine(boolean ignoreEmptyLines) throws IOException public String[] readAndSplitLine(boolean ignoreEmptyLines) throws IOException
{ {
//noinspection LoopConditionNotUpdatedInsideLoop
do do
{ {
String currentLine = lineReader.readLine(); String currentLine = lineReader.readLine();
@ -170,7 +173,7 @@ public class OBJLoader implements IModelLoader<OBJModel>
if (lineParts.size() > 0) if (lineParts.size() > 0)
return lineParts.toArray(new String[0]); return lineParts.toArray(new String[0]);
} }
while (ignoreEmptyLines); // conditional expression is not updated, yes, I know. while (ignoreEmptyLines);
return new String[0]; return new String[0];
} }
@ -183,22 +186,26 @@ public class OBJLoader implements IModelLoader<OBJModel>
} }
} }
private class ModelSettings public static class ModelSettings
{ {
@Nonnull @Nonnull
private final ResourceLocation modelLocation; public final ResourceLocation modelLocation;
private final boolean detectCullableFaces; public final boolean detectCullableFaces;
private final boolean diffuseLighting; public final boolean diffuseLighting;
private final boolean flipV; public final boolean flipV;
private final boolean ambientToFullbright; public final boolean ambientToFullbright;
@Nullable
public final String materialLibraryOverrideLocation;
public ModelSettings(@Nonnull ResourceLocation modelLocation, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright) public ModelSettings(@Nonnull ResourceLocation modelLocation, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright,
@Nullable String materialLibraryOverrideLocation)
{ {
this.modelLocation = modelLocation; this.modelLocation = modelLocation;
this.detectCullableFaces = detectCullableFaces; this.detectCullableFaces = detectCullableFaces;
this.diffuseLighting = diffuseLighting; this.diffuseLighting = diffuseLighting;
this.flipV = flipV; this.flipV = flipV;
this.ambientToFullbright = ambientToFullbright; this.ambientToFullbright = ambientToFullbright;
this.materialLibraryOverrideLocation = materialLibraryOverrideLocation;
} }
@Override @Override
@ -216,13 +223,14 @@ public class OBJLoader implements IModelLoader<OBJModel>
diffuseLighting == that.diffuseLighting && diffuseLighting == that.diffuseLighting &&
flipV == that.flipV && flipV == that.flipV &&
ambientToFullbright == that.ambientToFullbright && ambientToFullbright == that.ambientToFullbright &&
modelLocation.equals(that.modelLocation); modelLocation.equals(that.modelLocation) &&
Objects.equals(materialLibraryOverrideLocation, that.materialLibraryOverrideLocation);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return Objects.hash(modelLocation, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright); return Objects.hash(modelLocation, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation);
} }
} }
} }

View file

@ -73,13 +73,18 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
public final ResourceLocation modelLocation; public final ResourceLocation modelLocation;
OBJModel(ResourceLocation modelLocation, OBJLoader.LineReader reader, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright) throws IOException @Nullable
public final String materialLibraryOverrideLocation;
OBJModel(OBJLoader.LineReader reader, OBJLoader.ModelSettings settings) throws IOException
{ {
this.modelLocation = modelLocation; this.modelLocation = settings.modelLocation;
this.detectCullableFaces = detectCullableFaces; this.detectCullableFaces = settings.detectCullableFaces;
this.diffuseLighting = diffuseLighting; this.diffuseLighting = settings.diffuseLighting;
this.flipV = flipV; this.flipV = settings.flipV;
this.ambientToFullbright = ambientToFullbright; this.ambientToFullbright = settings.ambientToFullbright;
this.materialLibraryOverrideLocation = settings.materialLibraryOverrideLocation;
// for relative references to material libraries // for relative references to material libraries
String modelDomain = modelLocation.getNamespace(); String modelDomain = modelLocation.getNamespace();
@ -90,7 +95,7 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
else else
modelPath = ""; modelPath = "";
MaterialLibrary mtllib = null; MaterialLibrary mtllib = MaterialLibrary.EMPTY;
MaterialLibrary.Material currentMat = null; MaterialLibrary.Material currentMat = null;
String currentSmoothingGroup = null; String currentSmoothingGroup = null;
ModelGroup currentGroup = null; ModelGroup currentGroup = null;
@ -99,6 +104,15 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
boolean objAboveGroup = false; boolean objAboveGroup = false;
if (materialLibraryOverrideLocation != null)
{
String lib = materialLibraryOverrideLocation;
if (lib.contains(":"))
mtllib = OBJLoader.INSTANCE.loadMaterialLibrary(new ResourceLocation(lib));
else
mtllib = OBJLoader.INSTANCE.loadMaterialLibrary(new ResourceLocation(modelDomain, modelPath + lib));
}
String[] line; String[] line;
while((line = reader.readAndSplitLine(true)) != null) while((line = reader.readAndSplitLine(true)) != null)
{ {
@ -106,6 +120,9 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
{ {
case "mtllib": // Loads material library case "mtllib": // Loads material library
{ {
if (materialLibraryOverrideLocation != null)
break;
String lib = line[1]; String lib = line[1];
if (lib.contains(":")) if (lib.contains(":"))
mtllib = OBJLoader.INSTANCE.loadMaterialLibrary(new ResourceLocation(lib)); mtllib = OBJLoader.INSTANCE.loadMaterialLibrary(new ResourceLocation(lib));

View file

@ -1,3 +1,22 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2019.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.debug.client.model; package net.minecraftforge.debug.client.model;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;