OBJ loader: fixed another whitespace-related issue; removed unused "modifyUVs" property for now; added the "flip-v" property to switch between OpenGL-style and DirextX-style model UVs; fixed normals - they are now correct in-world, still a bit strange for the items; fixed normals a little bit for B3D models too.
This commit is contained in:
parent
c3b15e3f6c
commit
12e6fe9db7
3 changed files with 255 additions and 286 deletions
|
@ -582,11 +582,11 @@ public class B3DLoader implements ICustomModelLoader
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
if(v.getNormal() != null)
|
if(v.getNormal() != null)
|
||||||
{
|
{
|
||||||
builder.put(e, v.getNormal().x, v.getNormal().y, v.getNormal().z, 1);
|
builder.put(e, v.getNormal().x, v.getNormal().y, v.getNormal().z, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
builder.put(e, faceNormal.x, faceNormal.y, faceNormal.z, 1);
|
builder.put(e, faceNormal.x, faceNormal.y, faceNormal.z, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.vecmath.Matrix3f;
|
||||||
import javax.vecmath.Matrix4f;
|
import javax.vecmath.Matrix4f;
|
||||||
import javax.vecmath.Quat4f;
|
import javax.vecmath.Quat4f;
|
||||||
import javax.vecmath.Vector2f;
|
import javax.vecmath.Vector2f;
|
||||||
|
@ -625,7 +626,8 @@ public class B3DModel
|
||||||
bm.mul(bone.getLeft());
|
bm.mul(bone.getLeft());
|
||||||
t.add(bm);
|
t.add(bm);
|
||||||
}
|
}
|
||||||
if(totalWeight != 0) t.mul(1f / totalWeight);
|
if(Math.abs(totalWeight) > 1e-4) t.mul(1f / totalWeight);
|
||||||
|
else t.setIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
// pos
|
// pos
|
||||||
|
@ -635,12 +637,12 @@ public class B3DModel
|
||||||
Vector3f rPos = new Vector3f(newPos.x / newPos.w, newPos.y / newPos.w, newPos.z / newPos.w);
|
Vector3f rPos = new Vector3f(newPos.x / newPos.w, newPos.y / newPos.w, newPos.z / newPos.w);
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
t.invert();
|
Matrix3f tm = new Matrix3f();
|
||||||
t.transpose();
|
t.getRotationScale(tm);
|
||||||
Vector4f normal = new Vector4f(this.normal), newNormal = new Vector4f();
|
tm.invert();
|
||||||
normal.w = 1;
|
tm.transpose();
|
||||||
t.transform(normal, newNormal);
|
Vector3f normal = new Vector3f(this.normal), rNormal = new Vector3f();
|
||||||
Vector3f rNormal = new Vector3f(newNormal.x / newNormal.w, newNormal.y / newNormal.w, newNormal.z / newNormal.w);
|
tm.transform(normal, rNormal);
|
||||||
rNormal.normalize();
|
rNormal.normalize();
|
||||||
|
|
||||||
// texCoords TODO
|
// texCoords TODO
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.vecmath.Matrix3f;
|
||||||
import javax.vecmath.Matrix4f;
|
import javax.vecmath.Matrix4f;
|
||||||
import javax.vecmath.Vector2f;
|
import javax.vecmath.Vector2f;
|
||||||
import javax.vecmath.Vector3f;
|
import javax.vecmath.Vector3f;
|
||||||
|
@ -69,7 +70,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
|
|
||||||
public OBJModel(MaterialLibrary matLib, ResourceLocation modelLocation)
|
public OBJModel(MaterialLibrary matLib, ResourceLocation modelLocation)
|
||||||
{
|
{
|
||||||
this(matLib, modelLocation, null);
|
this(matLib, modelLocation, new CustomData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public OBJModel(MaterialLibrary matLib, ResourceLocation modelLocation, CustomData customData)
|
public OBJModel(MaterialLibrary matLib, ResourceLocation modelLocation, CustomData customData)
|
||||||
|
@ -131,16 +132,11 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
return this.matLib;
|
return this.matLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCustomData()
|
|
||||||
{
|
|
||||||
return this.customData != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IModel process(ImmutableMap<String, String> customData)
|
public IModel process(ImmutableMap<String, String> customData)
|
||||||
{
|
{
|
||||||
OBJModel ret = new OBJModel(this.matLib, this.modelLocation, new CustomData(customData));
|
OBJModel ret = new OBJModel(this.matLib, this.modelLocation, new CustomData(this.customData, customData));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,35 +146,44 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
OBJModel ret = new OBJModel(this.matLib.makeLibWithReplacements(textures), this.modelLocation, this.customData);
|
OBJModel ret = new OBJModel(this.matLib.makeLibWithReplacements(textures), this.modelLocation, this.customData);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CustomData
|
static class CustomData
|
||||||
{
|
{
|
||||||
public boolean ambientOcclusion = true;
|
public boolean ambientOcclusion = true;
|
||||||
public boolean gui3d = true;
|
public boolean gui3d = true;
|
||||||
public boolean modifyUVs = false;
|
// should be an enum, TODO
|
||||||
|
//public boolean modifyUVs = false;
|
||||||
public CustomData(ImmutableMap<String, String> customData)
|
public boolean flipV = false;
|
||||||
{
|
|
||||||
this.process(customData);
|
public CustomData(CustomData parent, ImmutableMap<String, String> customData)
|
||||||
}
|
{
|
||||||
|
this.ambientOcclusion = parent.ambientOcclusion;
|
||||||
public void process(ImmutableMap<String, String> customData)
|
this.gui3d = parent.gui3d;
|
||||||
{
|
this.flipV = parent.flipV;
|
||||||
for (Map.Entry<String, String> e : customData.entrySet())
|
this.process(customData);
|
||||||
{
|
}
|
||||||
if (e.getKey().equals("ambient"))
|
|
||||||
this.ambientOcclusion = Boolean.valueOf(e.getValue());
|
public CustomData() {}
|
||||||
else if (e.getKey().equals("gui3d"))
|
|
||||||
this.gui3d = Boolean.valueOf(e.getValue());
|
public void process(ImmutableMap<String, String> customData)
|
||||||
else if (e.getKey().equals("modifyUVs"))
|
{
|
||||||
this.modifyUVs = Boolean.valueOf(e.getValue());
|
for (Map.Entry<String, String> e : customData.entrySet())
|
||||||
}
|
{
|
||||||
}
|
if (e.getKey().equals("ambient"))
|
||||||
|
this.ambientOcclusion = Boolean.valueOf(e.getValue());
|
||||||
|
else if (e.getKey().equals("gui3d"))
|
||||||
|
this.gui3d = Boolean.valueOf(e.getValue());
|
||||||
|
/*else if (e.getKey().equals("modifyUVs"))
|
||||||
|
this.modifyUVs = Boolean.valueOf(e.getValue());*/
|
||||||
|
else if (e.getKey().equals("flip-v"))
|
||||||
|
this.flipV = Boolean.valueOf(e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Parser
|
public static class Parser
|
||||||
{
|
{
|
||||||
private static final Pattern WHITE_SPACE = Pattern.compile("\\s+");
|
private static final Pattern WHITE_SPACE = Pattern.compile("\\s+");
|
||||||
private static Set<String> unknownObjectCommands = new HashSet<String>();
|
private static Set<String> unknownObjectCommands = new HashSet<String>();
|
||||||
public MaterialLibrary materialLibrary = new MaterialLibrary();
|
public MaterialLibrary materialLibrary = new MaterialLibrary();
|
||||||
private IResourceManager manager;
|
private IResourceManager manager;
|
||||||
|
@ -209,7 +214,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
String currentLine = "";
|
String currentLine = "";
|
||||||
Material material = new Material();
|
Material material = new Material();
|
||||||
int usemtlCounter = 0;
|
int usemtlCounter = 0;
|
||||||
|
|
||||||
// float[] minUVBounds = new float[] {0.0f, 0.0f};
|
// float[] minUVBounds = new float[] {0.0f, 0.0f};
|
||||||
// float[] maxUVBounds = new float[] {1.0f, 1.0f};
|
// float[] maxUVBounds = new float[] {1.0f, 1.0f};
|
||||||
|
|
||||||
|
@ -217,8 +222,9 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
currentLine = objReader.readLine();
|
currentLine = objReader.readLine();
|
||||||
if (currentLine == null) break;
|
if (currentLine == null) break;
|
||||||
|
currentLine.trim();
|
||||||
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
|
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
|
||||||
|
|
||||||
String[] fields = WHITE_SPACE.split(currentLine, 2);
|
String[] fields = WHITE_SPACE.split(currentLine, 2);
|
||||||
String key = fields[0];
|
String key = fields[0];
|
||||||
String data = fields[1];
|
String data = fields[1];
|
||||||
|
@ -255,14 +261,14 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
floatSplitData[i] = Float.parseFloat(splitData[i]);
|
floatSplitData[i] = Float.parseFloat(splitData[i]);
|
||||||
TextureCoordinate texCoord = new TextureCoordinate(new Vector3f(floatSplitData[0], floatSplitData[1], floatSplitData.length == 3 ? floatSplitData[2] : 1));
|
TextureCoordinate texCoord = new TextureCoordinate(new Vector3f(floatSplitData[0], floatSplitData[1], floatSplitData.length == 3 ? floatSplitData[2] : 1));
|
||||||
if (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f)
|
if (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f)
|
||||||
throw new UVsOutOfBoundsException(this.objFrom);
|
throw new UVsOutOfBoundsException(this.objFrom);
|
||||||
// this.UVsOutOfBounds = (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f);
|
// this.UVsOutOfBounds = (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f);
|
||||||
|
|
||||||
// if (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f)
|
// if (texCoord.u < 0.0f || texCoord.u > 1.0f || texCoord.v < 0.0f || texCoord.v > 1.0f)
|
||||||
// {
|
// {
|
||||||
// this.UVsOutOfBounds = true;
|
// this.UVsOutOfBounds = true;
|
||||||
// texCoord.u -= Math.floor(texCoord.u);
|
// texCoord.u -= Math.floor(texCoord.u);
|
||||||
// texCoord.v -= Math.floor(texCoord.v);
|
// texCoord.v -= Math.floor(texCoord.v);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// minUVBounds[0] = floatSplitData[0] < minUVBounds[0] ? floatSplitData[0] : minUVBounds[0];
|
// minUVBounds[0] = floatSplitData[0] < minUVBounds[0] ? floatSplitData[0] : minUVBounds[0];
|
||||||
|
@ -297,7 +303,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
norm = norm < 0 ? this.normals.size() - 1 : norm - 1;
|
norm = norm < 0 ? this.normals.size() - 1 : norm - 1;
|
||||||
|
|
||||||
this.vertices.get(vert).setNormal(this.normals.get(norm));
|
this.vertices.get(vert).setNormal(this.normals.get(norm));
|
||||||
|
|
||||||
v.add(this.vertices.get(vert));
|
v.add(this.vertices.get(vert));
|
||||||
// n.add(this.normals.get(norm));
|
// n.add(this.normals.get(norm));
|
||||||
}
|
}
|
||||||
|
@ -314,7 +320,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
norm = Integer.parseInt(splitSlash[i][2]);
|
norm = Integer.parseInt(splitSlash[i][2]);
|
||||||
norm = norm < 0 ? this.normals.size() - 1 : norm - 1;
|
norm = norm < 0 ? this.normals.size() - 1 : norm - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.vertices.get(vert).setTextureCoordinate(this.texCoords.get(texCoord));
|
this.vertices.get(vert).setTextureCoordinate(this.texCoords.get(texCoord));
|
||||||
this.vertices.get(vert).setNormal(splitSlash[i].length > 2 ? this.normals.get(norm) : null);
|
this.vertices.get(vert).setNormal(splitSlash[i].length > 2 ? this.normals.get(norm) : null);
|
||||||
|
|
||||||
|
@ -401,8 +407,8 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJModel model = new OBJModel(this.materialLibrary, this.objFrom, null);
|
OBJModel model = new OBJModel(this.materialLibrary, this.objFrom);
|
||||||
// model.getMatLib().setUVBounds(minUVBounds[0], maxUVBounds[0], minUVBounds[1], maxUVBounds[1]);
|
// model.getMatLib().setUVBounds(minUVBounds[0], maxUVBounds[0], minUVBounds[1], maxUVBounds[1]);
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
@ -410,7 +416,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
|
|
||||||
public static class MaterialLibrary
|
public static class MaterialLibrary
|
||||||
{
|
{
|
||||||
private static final Pattern WHITE_SPACE = Pattern.compile("\\s+");
|
private static final Pattern WHITE_SPACE = Pattern.compile("\\s+");
|
||||||
private Set<String> unknownMaterialCommands = new HashSet<String>();
|
private Set<String> unknownMaterialCommands = new HashSet<String>();
|
||||||
private Map<String, Material> materials = new HashMap<String, Material>();
|
private Map<String, Material> materials = new HashMap<String, Material>();
|
||||||
private Map<String, Group> groups = new HashMap<String, Group>();
|
private Map<String, Group> groups = new HashMap<String, Group>();
|
||||||
|
@ -424,9 +430,9 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
this.groups.put(Group.DEFAULT_NAME, new Group(Group.DEFAULT_NAME, null));
|
this.groups.put(Group.DEFAULT_NAME, new Group(Group.DEFAULT_NAME, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialLibrary makeLibWithReplacements(ImmutableMap<String, String> replacements)
|
public MaterialLibrary makeLibWithReplacements(ImmutableMap<String, String> replacements)
|
||||||
{
|
{
|
||||||
Map<String, Material> mats = new HashMap<String, Material>();
|
Map<String, Material> mats = new HashMap<String, Material>();
|
||||||
for (Map.Entry<String, Material> e : this.materials.entrySet())
|
for (Map.Entry<String, Material> e : this.materials.entrySet())
|
||||||
{
|
{
|
||||||
|
@ -453,14 +459,14 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public float[] getMinUVBounds()
|
// public float[] getMinUVBounds()
|
||||||
// {
|
// {
|
||||||
// return this.minUVBounds;
|
// return this.minUVBounds;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// public float[] getMaxUVBounds()
|
// public float[] getMaxUVBounds()
|
||||||
// {
|
// {
|
||||||
// return this.maxUVBounds;
|
// return this.maxUVBounds;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// public void setUVBounds(float minU, float maxU, float minV, float maxV)
|
// public void setUVBounds(float minU, float maxU, float minV, float maxV)
|
||||||
|
@ -512,8 +518,8 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
boolean hasSetTexture = false;
|
boolean hasSetTexture = false;
|
||||||
boolean hasSetColor = false;
|
boolean hasSetColor = false;
|
||||||
String domain = from.getResourceDomain();
|
String domain = from.getResourceDomain();
|
||||||
if (!path.contains("/"))
|
if (!path.contains("/"))
|
||||||
path = from.getResourcePath().substring(0, from.getResourcePath().lastIndexOf("/") + 1) + path;
|
path = from.getResourcePath().substring(0, from.getResourcePath().lastIndexOf("/") + 1) + path;
|
||||||
mtlStream = new InputStreamReader(manager.getResource(new ResourceLocation(domain, path)).getInputStream(), Charsets.UTF_8);
|
mtlStream = new InputStreamReader(manager.getResource(new ResourceLocation(domain, path)).getInputStream(), Charsets.UTF_8);
|
||||||
mtlReader = new BufferedReader(mtlStream);
|
mtlReader = new BufferedReader(mtlStream);
|
||||||
|
|
||||||
|
@ -528,6 +534,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
currentLine = mtlReader.readLine();
|
currentLine = mtlReader.readLine();
|
||||||
if (currentLine == null) break;
|
if (currentLine == null) break;
|
||||||
|
currentLine.trim();
|
||||||
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
|
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue;
|
||||||
|
|
||||||
String[] fields = WHITE_SPACE.split(currentLine, 2);
|
String[] fields = WHITE_SPACE.split(currentLine, 2);
|
||||||
|
@ -582,11 +589,11 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
}
|
}
|
||||||
else if (key.equalsIgnoreCase("d") || key.equalsIgnoreCase("Tr"))
|
else if (key.equalsIgnoreCase("d") || key.equalsIgnoreCase("Tr"))
|
||||||
{
|
{
|
||||||
//d <-optional key here> float[0.0:1.0, 1.0]
|
//d <-optional key here> float[0.0:1.0, 1.0]
|
||||||
//Tr r g b OR Tr spectral map file OR Tr xyz r g b (CIEXYZ colorspace)
|
//Tr r g b OR Tr spectral map file OR Tr xyz r g b (CIEXYZ colorspace)
|
||||||
String[] splitData = WHITE_SPACE.split(data);
|
String[] splitData = WHITE_SPACE.split(data);
|
||||||
float alpha = Float.parseFloat(splitData[splitData.length - 1]);
|
float alpha = Float.parseFloat(splitData[splitData.length - 1]);
|
||||||
material.getColor().setW(alpha);
|
material.getColor().setW(alpha);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -756,11 +763,11 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
this(verts, Material.DEFAULT_NAME);
|
this(verts, Material.DEFAULT_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Face(Vertex[] verts, String materialName) {
|
public Face(Vertex[] verts, String materialName) {
|
||||||
this.verts = verts != null && verts.length > 2 ? verts : null;
|
this.verts = verts != null && verts.length > 2 ? verts : null;
|
||||||
setMaterialName(materialName);
|
setMaterialName(materialName);
|
||||||
checkData();
|
checkData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public Face(Vertex[] verts, Normal[] norms)
|
// public Face(Vertex[] verts, Normal[] norms)
|
||||||
|
@ -780,9 +787,9 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
|
|
||||||
// public Face(Vertex[] verts, Normal[] norms, TextureCoordinate[] texCoords, String materialName)
|
// public Face(Vertex[] verts, Normal[] norms, TextureCoordinate[] texCoords, String materialName)
|
||||||
// {
|
// {
|
||||||
// this.verts = verts != null && verts.length > 2 ? verts : null;
|
// this.verts = verts != null && verts.length > 2 ? verts : null;
|
||||||
// this.norms = norms != null && norms.length > 2 ? norms : null;
|
// this.norms = norms != null && norms.length > 2 ? norms : null;
|
||||||
// this.texCoords = texCoords != null && texCoords.length > 2 ? texCoords : null;
|
// this.texCoords = texCoords != null && texCoords.length > 2 ? texCoords : null;
|
||||||
// setMaterialName(materialName);
|
// setMaterialName(materialName);
|
||||||
// checkData();
|
// checkData();
|
||||||
// }
|
// }
|
||||||
|
@ -791,7 +798,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
if (this.verts != null && this.verts.length == 3)
|
if (this.verts != null && this.verts.length == 3)
|
||||||
{
|
{
|
||||||
this.isTri = true;
|
this.isTri = true;
|
||||||
this.verts = new Vertex[]{this.verts[0], this.verts[1], this.verts[2], this.verts[2]};
|
this.verts = new Vertex[]{this.verts[0], this.verts[1], this.verts[2], this.verts[2]};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,40 +829,40 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
// public boolean areUVsNormalized()
|
// public boolean areUVsNormalized()
|
||||||
// {
|
// {
|
||||||
// for (Vertex v : this.verts)
|
// for (Vertex v : this.verts)
|
||||||
// if (!v.hasNormalizedUVs())
|
// if (!v.hasNormalizedUVs())
|
||||||
// return false;
|
// return false;
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// public void normalizeUVs(float[] min, float[] max)
|
// public void normalizeUVs(float[] min, float[] max)
|
||||||
// {
|
// {
|
||||||
// if (!this.areUVsNormalized())
|
// if (!this.areUVsNormalized())
|
||||||
// {
|
// {
|
||||||
// for (int i = 0; i < this.verts.length; i++) {
|
// for (int i = 0; i < this.verts.length; i++) {
|
||||||
// TextureCoordinate texCoord = this.verts[i].getTextureCoordinate();
|
// TextureCoordinate texCoord = this.verts[i].getTextureCoordinate();
|
||||||
// min[0] = texCoord.u < min[0] ? texCoord.u : min[0];
|
// min[0] = texCoord.u < min[0] ? texCoord.u : min[0];
|
||||||
// max[0] = texCoord.u > max[0] ? texCoord.u : max[0];
|
// max[0] = texCoord.u > max[0] ? texCoord.u : max[0];
|
||||||
// min[1] = texCoord.v < min[1] ? texCoord.v : min[1];
|
// min[1] = texCoord.v < min[1] ? texCoord.v : min[1];
|
||||||
// max[1] = texCoord.v > max[1] ? texCoord.v : max[1];
|
// max[1] = texCoord.v > max[1] ? texCoord.v : max[1];
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// for (Vertex v : this.verts) {
|
// for (Vertex v : this.verts) {
|
||||||
// v.texCoord.u = (v.texCoord.u - min[0]) / (max[0] - min[0]);
|
// v.texCoord.u = (v.texCoord.u - min[0]) / (max[0] - min[0]);
|
||||||
// v.texCoord.v = (v.texCoord.v - min[1]) / (max[1] - max[1]);
|
// v.texCoord.v = (v.texCoord.v - min[1]) / (max[1] - max[1]);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public Face bake(TRSRTransformation transform)
|
public Face bake(TRSRTransformation transform)
|
||||||
{
|
{
|
||||||
Matrix4f m = transform.getMatrix();
|
Matrix4f m = transform.getMatrix();
|
||||||
|
Matrix3f mn = null;
|
||||||
Vertex[] vertices = new Vertex[verts.length];
|
Vertex[] vertices = new Vertex[verts.length];
|
||||||
// Normal[] normals = norms != null ? new Normal[norms.length] : null;
|
// Normal[] normals = norms != null ? new Normal[norms.length] : null;
|
||||||
// TextureCoordinate[] textureCoords = texCoords != null ? new TextureCoordinate[texCoords.length] : null;
|
// TextureCoordinate[] textureCoords = texCoords != null ? new TextureCoordinate[texCoords.length] : null;
|
||||||
|
|
||||||
for (int i = 0; i < verts.length; i++)
|
for (int i = 0; i < verts.length; i++)
|
||||||
{
|
{
|
||||||
m = transform.getMatrix();
|
|
||||||
Vertex v = verts[i];
|
Vertex v = verts[i];
|
||||||
// Normal n = norms != null ? norms[i] : null;
|
// Normal n = norms != null ? norms[i] : null;
|
||||||
// TextureCoordinate t = texCoords != null ? texCoords[i] : null;
|
// TextureCoordinate t = texCoords != null ? texCoords[i] : null;
|
||||||
|
@ -864,34 +871,25 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
pos.w = 1;
|
pos.w = 1;
|
||||||
m.transform(pos, newPos);
|
m.transform(pos, newPos);
|
||||||
vertices[i] = new Vertex(newPos, v.getMaterial());
|
vertices[i] = new Vertex(newPos, v.getMaterial());
|
||||||
|
|
||||||
if (v.hasNormal())
|
if (v.hasNormal())
|
||||||
{
|
{
|
||||||
m.invert();
|
if(mn == null)
|
||||||
Vector4f normal = new Vector4f(v.getNormal().getData()), newNormal = new Vector4f();
|
{
|
||||||
normal.w = 1.0f;
|
mn = new Matrix3f();
|
||||||
m.transform(normal, newNormal);
|
m.getRotationScale(mn);
|
||||||
Vector3f rNormal = new Vector3f(newNormal.x / newNormal.w, newNormal.y / newNormal.w, newNormal.z / newNormal.w);
|
mn.invert();
|
||||||
rNormal.normalize();
|
mn.transpose();
|
||||||
vertices[i].setNormal(new Normal(rNormal));
|
}
|
||||||
|
Vector3f normal = new Vector3f(v.getNormal().getData()), newNormal = new Vector3f();
|
||||||
|
mn.transform(normal, newNormal);
|
||||||
|
newNormal.normalize();
|
||||||
|
vertices[i].setNormal(new Normal(newNormal));
|
||||||
}
|
}
|
||||||
else v.setNormal(new Normal(0.0f, 1.0f, 0.0f));
|
|
||||||
|
|
||||||
if (v.hasTextureCoordinate()) vertices[i].setTextureCoordinate(v.getTextureCoordinate());
|
if (v.hasTextureCoordinate()) vertices[i].setTextureCoordinate(v.getTextureCoordinate());
|
||||||
else v.setTextureCoordinate(TextureCoordinate.getDefaultUVs()[i]);
|
else v.setTextureCoordinate(TextureCoordinate.getDefaultUVs()[i]);
|
||||||
|
|
||||||
// if (n != null)
|
|
||||||
// {
|
|
||||||
// m.invert();
|
|
||||||
// m.transpose();
|
|
||||||
// Vector4f normal = new Vector4f(n.getData()), newNormal = new Vector4f();
|
|
||||||
// normal.w = 1;
|
|
||||||
// m.transform(normal, newNormal);
|
|
||||||
// Vector3f rNormal = new Vector3f(newNormal.x / newNormal.w, newNormal.y / newNormal.w, newNormal.z / newNormal.w);
|
|
||||||
// rNormal.normalize();
|
|
||||||
// normals[i] = new Normal(rNormal);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//texCoords TODO
|
//texCoords TODO
|
||||||
// if (t != null) textureCoords[i] = t;
|
// if (t != null) textureCoords[i] = t;
|
||||||
}
|
}
|
||||||
|
@ -900,40 +898,13 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
|
|
||||||
public Normal getNormal()
|
public Normal getNormal()
|
||||||
{
|
{
|
||||||
for (Vertex v : this.verts)
|
Vector3f a = this.verts[2].getPos3();
|
||||||
{
|
a.sub(this.verts[0].getPos3());
|
||||||
if (!v.hasNormal())
|
Vector3f b = this.verts[3].getPos3();
|
||||||
{
|
b.sub(this.verts[1].getPos3());
|
||||||
Vector3f vPos = v.getPos3();
|
a.cross(a, b);
|
||||||
vPos.normalize();
|
a.normalize();
|
||||||
v.setNormal(new Normal(vPos));
|
return new Normal(a);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f a = this.verts[1].getNormal().getData();
|
|
||||||
a.sub(this.verts[0].getNormal().getData());
|
|
||||||
Vector3f b = this.verts[2].getNormal().getData();
|
|
||||||
b.sub(this.verts[0].getNormal().getData());
|
|
||||||
Vector3f c = new Vector3f();
|
|
||||||
c.cross(a, b);
|
|
||||||
c.normalize();
|
|
||||||
|
|
||||||
if (this.isTri) return new Normal(c);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a = this.verts[1].getNormal().getData();
|
|
||||||
a.sub(this.verts[3].getNormal().getData());
|
|
||||||
b = this.verts[2].getNormal().getData();
|
|
||||||
b.sub(this.verts[3].getNormal().getData());
|
|
||||||
Vector3f c1 = new Vector3f();
|
|
||||||
c1.cross(a, b);
|
|
||||||
c1.normalize();
|
|
||||||
Vector3f normal = new Vector3f();
|
|
||||||
normal.add(c, c1);
|
|
||||||
normal.scale(0.5f);
|
|
||||||
normal.normalize();
|
|
||||||
return new Normal(normal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,45 +930,45 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
{
|
{
|
||||||
return this.position;
|
return this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getPos3()
|
public Vector3f getPos3()
|
||||||
{
|
{
|
||||||
return new Vector3f(this.position.x, this.position.y, this.position.z);
|
return new Vector3f(this.position.x, this.position.y, this.position.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNormal()
|
public boolean hasNormal()
|
||||||
{
|
{
|
||||||
return this.normal != null;
|
return this.normal != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNormal(Normal normal)
|
public void setNormal(Normal normal)
|
||||||
{
|
{
|
||||||
this.normal = normal;
|
this.normal = normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Normal getNormal()
|
public Normal getNormal()
|
||||||
{
|
{
|
||||||
return this.normal;
|
return this.normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasTextureCoordinate()
|
public boolean hasTextureCoordinate()
|
||||||
{
|
{
|
||||||
return this.texCoord != null;
|
return this.texCoord != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextureCoordinate(TextureCoordinate texCoord)
|
public void setTextureCoordinate(TextureCoordinate texCoord)
|
||||||
{
|
{
|
||||||
this.texCoord = texCoord;
|
this.texCoord = texCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureCoordinate getTextureCoordinate()
|
public TextureCoordinate getTextureCoordinate()
|
||||||
{
|
{
|
||||||
return this.texCoord;
|
return this.texCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public boolean hasNormalizedUVs()
|
// public boolean hasNormalizedUVs()
|
||||||
// {
|
// {
|
||||||
// return this.texCoord.u >= 0.0f && this.texCoord.u <= 1.0f && this.texCoord.v >= 0.0f && this.texCoord.v <= 1.0f;
|
// return this.texCoord.u >= 0.0f && this.texCoord.u <= 1.0f && this.texCoord.v >= 0.0f && this.texCoord.v <= 1.0f;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public void setMaterial(Material material)
|
public void setMaterial(Material material)
|
||||||
|
@ -1020,78 +991,78 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Normal
|
public static class Normal
|
||||||
{
|
{
|
||||||
public float x, y, z;
|
public float x, y, z;
|
||||||
|
|
||||||
public Normal()
|
public Normal()
|
||||||
{
|
{
|
||||||
this(0.0f, 0.0f, 0.0f);
|
this(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Normal(float[] data)
|
public Normal(float[] data)
|
||||||
{
|
{
|
||||||
this(data[0], data[1], data[2]);
|
this(data[0], data[1], data[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Normal(Vector3f vector3f)
|
public Normal(Vector3f vector3f)
|
||||||
{
|
{
|
||||||
this(vector3f.x, vector3f.y, vector3f.z);
|
this(vector3f.x, vector3f.y, vector3f.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Normal(float x, float y, float z) {
|
public Normal(float x, float y, float z) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getData()
|
public Vector3f getData()
|
||||||
{
|
{
|
||||||
return new Vector3f(this.x, this.y, this.z);
|
return new Vector3f(this.x, this.y, this.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TextureCoordinate
|
public static class TextureCoordinate
|
||||||
{
|
{
|
||||||
public float u, v, w;
|
public float u, v, w;
|
||||||
|
|
||||||
public TextureCoordinate()
|
public TextureCoordinate()
|
||||||
{
|
{
|
||||||
this(0.0f, 0.0f, 1.0f);
|
this(0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureCoordinate(float[] data)
|
public TextureCoordinate(float[] data)
|
||||||
{
|
{
|
||||||
this(data[0], data[1], data[2]);
|
this(data[0], data[1], data[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureCoordinate(Vector3f data)
|
public TextureCoordinate(Vector3f data)
|
||||||
{
|
{
|
||||||
this(data.x, data.y, data.z);
|
this(data.x, data.y, data.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureCoordinate(float u, float v, float w)
|
public TextureCoordinate(float u, float v, float w)
|
||||||
{
|
{
|
||||||
this.u = u;
|
this.u = u;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.w = w;
|
this.w = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3f getData()
|
public Vector3f getData()
|
||||||
{
|
{
|
||||||
return new Vector3f(this.u, this.v, this.w);
|
return new Vector3f(this.u, this.v, this.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureCoordinate[] getDefaultUVs()
|
public static TextureCoordinate[] getDefaultUVs()
|
||||||
{
|
{
|
||||||
TextureCoordinate[] texCoords = new TextureCoordinate[4];
|
TextureCoordinate[] texCoords = new TextureCoordinate[4];
|
||||||
texCoords[0] = new TextureCoordinate(0.0f, 0.0f, 1.0f);
|
texCoords[0] = new TextureCoordinate(0.0f, 0.0f, 1.0f);
|
||||||
texCoords[1] = new TextureCoordinate(1.0f, 0.0f, 1.0f);
|
texCoords[1] = new TextureCoordinate(1.0f, 0.0f, 1.0f);
|
||||||
texCoords[2] = new TextureCoordinate(1.0f, 1.0f, 1.0f);
|
texCoords[2] = new TextureCoordinate(1.0f, 1.0f, 1.0f);
|
||||||
texCoords[3] = new TextureCoordinate(0.0f, 1.0f, 1.0f);
|
texCoords[3] = new TextureCoordinate(0.0f, 1.0f, 1.0f);
|
||||||
return texCoords;
|
return texCoords;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Group implements IModelPart
|
public static class Group implements IModelPart
|
||||||
|
@ -1118,7 +1089,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
LinkedHashSet<Face> faceSet = new LinkedHashSet<Face>();
|
LinkedHashSet<Face> faceSet = new LinkedHashSet<Face>();
|
||||||
for (Face f : this.faces)
|
for (Face f : this.faces)
|
||||||
{
|
{
|
||||||
// if (minUVBounds != null && maxUVBounds != null) f.normalizeUVs(minUVBounds, maxUVBounds);
|
// if (minUVBounds != null && maxUVBounds != null) f.normalizeUVs(minUVBounds, maxUVBounds);
|
||||||
faceSet.add(f.bake(transform));
|
faceSet.add(f.bake(transform));
|
||||||
}
|
}
|
||||||
return faceSet;
|
return faceSet;
|
||||||
|
@ -1302,10 +1273,10 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
private Set<BakedQuad> quads;
|
private Set<BakedQuad> quads;
|
||||||
private ImmutableMap<String, TextureAtlasSprite> textures;
|
private ImmutableMap<String, TextureAtlasSprite> textures;
|
||||||
private TextureAtlasSprite sprite = ModelLoader.White.instance;
|
private TextureAtlasSprite sprite = ModelLoader.White.instance;
|
||||||
|
|
||||||
public OBJBakedModel(OBJModel model, IModelState state, VertexFormat format, ImmutableMap<String, TextureAtlasSprite> textures)
|
public OBJBakedModel(OBJModel model, IModelState state, VertexFormat format, ImmutableMap<String, TextureAtlasSprite> textures)
|
||||||
{
|
{
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
if (this.state instanceof OBJState) this.updateStateVisibilityMap((OBJState) this.state);
|
if (this.state instanceof OBJState) this.updateStateVisibilityMap((OBJState) this.state);
|
||||||
this.format = format;
|
this.format = format;
|
||||||
|
@ -1333,16 +1304,16 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
TRSRTransformation transform = TRSRTransformation.identity();
|
TRSRTransformation transform = TRSRTransformation.identity();
|
||||||
for (Group g : this.model.getMatLib().getGroups().values())
|
for (Group g : this.model.getMatLib().getGroups().values())
|
||||||
{
|
{
|
||||||
// g.minUVBounds = this.model.getMatLib().minUVBounds;
|
// g.minUVBounds = this.model.getMatLib().minUVBounds;
|
||||||
// g.maxUVBounds = this.model.getMatLib().maxUVBounds;
|
// g.maxUVBounds = this.model.getMatLib().maxUVBounds;
|
||||||
// FMLLog.info("Group: %s u: [%f, %f] v: [%f, %f]", g.name, g.minUVBounds[0], g.maxUVBounds[0], g.minUVBounds[1], g.maxUVBounds[1]);
|
// FMLLog.info("Group: %s u: [%f, %f] v: [%f, %f]", g.name, g.minUVBounds[0], g.maxUVBounds[0], g.minUVBounds[1], g.maxUVBounds[1]);
|
||||||
|
|
||||||
if (this.state instanceof OBJState)
|
if (this.state instanceof OBJState)
|
||||||
{
|
{
|
||||||
OBJState state = (OBJState) this.state;
|
OBJState state = (OBJState) this.state;
|
||||||
if (state.parent != null && state.parent instanceof TRSRTransformation)
|
if (state.parent != null)
|
||||||
{
|
{
|
||||||
transform = (TRSRTransformation) state.parent;
|
transform = state.parent.apply(model);
|
||||||
}
|
}
|
||||||
//TODO: can this be replaced by updateStateVisibilityMap(OBJState)?
|
//TODO: can this be replaced by updateStateVisibilityMap(OBJState)?
|
||||||
if (state.getGroupNamesFromMap().contains(Group.ALL))
|
if (state.getGroupNamesFromMap().contains(Group.ALL))
|
||||||
|
@ -1377,14 +1348,9 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
faces.addAll(g.applyTransform(transform));
|
faces.addAll(g.applyTransform(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this.state instanceof TRSRTransformation)
|
|
||||||
{
|
|
||||||
transform = (TRSRTransformation) this.state;
|
|
||||||
faces.addAll(g.applyTransform(transform));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
transform = TRSRTransformation.identity();
|
transform = state.apply(model);
|
||||||
faces.addAll(g.applyTransform(transform));
|
faces.addAll(g.applyTransform(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1404,10 +1370,11 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
|
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
|
||||||
builder.setQuadOrientation(EnumFacing.getFacingFromVector(f.getNormal().x, f.getNormal().y, f.getNormal().z));
|
builder.setQuadOrientation(EnumFacing.getFacingFromVector(f.getNormal().x, f.getNormal().y, f.getNormal().z));
|
||||||
builder.setQuadColored();
|
builder.setQuadColored();
|
||||||
putVertexData(builder, f.verts[0], f.getNormal(), TextureCoordinate.getDefaultUVs()[0], sprite);
|
Normal faceNormal = f.getNormal();
|
||||||
putVertexData(builder, f.verts[1], f.getNormal(), TextureCoordinate.getDefaultUVs()[1], sprite);
|
putVertexData(builder, f.verts[0], faceNormal, TextureCoordinate.getDefaultUVs()[0], sprite);
|
||||||
putVertexData(builder, f.verts[2], f.getNormal(), TextureCoordinate.getDefaultUVs()[2], sprite);
|
putVertexData(builder, f.verts[1], faceNormal, TextureCoordinate.getDefaultUVs()[1], sprite);
|
||||||
putVertexData(builder, f.verts[3], f.getNormal(), TextureCoordinate.getDefaultUVs()[3], sprite);
|
putVertexData(builder, f.verts[2], faceNormal, TextureCoordinate.getDefaultUVs()[2], sprite);
|
||||||
|
putVertexData(builder, f.verts[3], faceNormal, TextureCoordinate.getDefaultUVs()[3], sprite);
|
||||||
quads.add(builder.build());
|
quads.add(builder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1426,37 +1393,37 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
break;
|
break;
|
||||||
case COLOR:
|
case COLOR:
|
||||||
float d;
|
float d;
|
||||||
if (v.hasNormal())
|
if (v.hasNormal())
|
||||||
d = LightUtil.diffuseLight(v.getNormal().x, v.getNormal().y, v.getNormal().z);
|
d = LightUtil.diffuseLight(v.getNormal().x, v.getNormal().y, v.getNormal().z);
|
||||||
else
|
else
|
||||||
d = LightUtil.diffuseLight(faceNormal.x, faceNormal.y, faceNormal.z);
|
d = LightUtil.diffuseLight(faceNormal.x, faceNormal.y, faceNormal.z);
|
||||||
|
|
||||||
if (v.getMaterial() != null)
|
if (v.getMaterial() != null)
|
||||||
builder.put(e,
|
builder.put(e,
|
||||||
d * v.getMaterial().getColor().x,
|
d * v.getMaterial().getColor().x,
|
||||||
d * v.getMaterial().getColor().y,
|
d * v.getMaterial().getColor().y,
|
||||||
d * v.getMaterial().getColor().z,
|
d * v.getMaterial().getColor().z,
|
||||||
v.getMaterial().getColor().w);
|
v.getMaterial().getColor().w);
|
||||||
else
|
else
|
||||||
builder.put(e, d, d, d, 1);
|
builder.put(e, d, d, d, 1);
|
||||||
break;
|
break;
|
||||||
case UV:
|
case UV:
|
||||||
if (!v.hasTextureCoordinate())
|
if (!v.hasTextureCoordinate())
|
||||||
builder.put(e,
|
builder.put(e,
|
||||||
sprite.getInterpolatedU(defUV.u * 16),
|
sprite.getInterpolatedU(defUV.u * 16),
|
||||||
sprite.getInterpolatedV(defUV.v * 16),
|
sprite.getInterpolatedV((model.customData.flipV ? 1 - defUV.v: defUV.v) * 16),
|
||||||
0, 1);
|
0, 1);
|
||||||
else
|
else
|
||||||
builder.put(e,
|
builder.put(e,
|
||||||
sprite.getInterpolatedU(v.getTextureCoordinate().u * 16),
|
sprite.getInterpolatedU(v.getTextureCoordinate().u * 16),
|
||||||
sprite.getInterpolatedV(v.getTextureCoordinate().v * 16),
|
sprite.getInterpolatedV((model.customData.flipV ? 1 - v.getTextureCoordinate().v : v.getTextureCoordinate().v) * 16),
|
||||||
0, 1);
|
0, 1);
|
||||||
break;
|
break;
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
if (!v.hasNormal())
|
if (!v.hasNormal())
|
||||||
builder.put(e, faceNormal.x, faceNormal.y, faceNormal.z, 1);
|
builder.put(e, faceNormal.x, faceNormal.y, faceNormal.z, 0);
|
||||||
else
|
else
|
||||||
builder.put(e, v.getNormal().x, v.getNormal().y, v.getNormal().z, 1);
|
builder.put(e, v.getNormal().x, v.getNormal().y, v.getNormal().z, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
builder.put(e);
|
builder.put(e);
|
||||||
|
@ -1467,13 +1434,13 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
@Override
|
@Override
|
||||||
public boolean isAmbientOcclusion()
|
public boolean isAmbientOcclusion()
|
||||||
{
|
{
|
||||||
return model != null && model.hasCustomData() ? model.customData.ambientOcclusion : true;
|
return model != null ? model.customData.ambientOcclusion : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isGui3d()
|
public boolean isGui3d()
|
||||||
{
|
{
|
||||||
return model != null && model.hasCustomData() ? model.customData.gui3d : true;
|
return model != null ? model.customData.gui3d : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1527,7 +1494,7 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStateVisibilityMap(OBJState state)
|
private void updateStateVisibilityMap(OBJState state)
|
||||||
{
|
{
|
||||||
if (state.visibilityMap.containsKey(Group.ALL))
|
if (state.visibilityMap.containsKey(Group.ALL))
|
||||||
|
@ -1602,16 +1569,16 @@ public class OBJModel implements IRetexturableModel, IModelCustomData
|
||||||
return this.model.modelLocation.toString();
|
return this.model.modelLocation.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class UVsOutOfBoundsException extends RuntimeException
|
public static class UVsOutOfBoundsException extends RuntimeException
|
||||||
{
|
{
|
||||||
public ResourceLocation modelLocation;
|
public ResourceLocation modelLocation;
|
||||||
|
|
||||||
public UVsOutOfBoundsException(ResourceLocation modelLocation)
|
public UVsOutOfBoundsException(ResourceLocation modelLocation)
|
||||||
{
|
{
|
||||||
super(String.format("Model '%s' has UVs ('vt') out of bounds 0-1! The missing model will be used instead. Support for UV processing will be added to the OBJ loader in the future.", modelLocation));
|
super(String.format("Model '%s' has UVs ('vt') out of bounds 0-1! The missing model will be used instead. Support for UV processing will be added to the OBJ loader in the future.", modelLocation));
|
||||||
this.modelLocation = modelLocation;
|
this.modelLocation = modelLocation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue