Last active
August 29, 2015 14:27
-
-
Save StillManic/5cc256aad1d6e61f18e1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rcteam.rc2.proxy; | |
import cpw.mods.fml.client.registry.ClientRegistry; | |
import cpw.mods.fml.common.registry.GameRegistry; | |
import net.minecraft.client.Minecraft; | |
import net.minecraft.client.renderer.texture.TextureAtlasSprite; | |
import net.minecraft.client.renderer.texture.TextureMap; | |
import net.minecraft.client.resources.IResourceManager; | |
import net.minecraft.item.Item; | |
import net.minecraft.util.ResourceLocation; | |
import net.minecraftforge.client.MinecraftForgeClient; | |
import net.minecraftforge.common.MinecraftForge; | |
import rcteam.rc2.block.RC2Blocks; | |
import rcteam.rc2.block.te.TileEntityTrack; | |
import rcteam.rc2.client.gui.GuiThemeParkOverlay; | |
import rcteam.rc2.client.rendering.ItemTrackRenderer; | |
import rcteam.rc2.client.rendering.TileEntityTrackRenderer; | |
import rcteam.rc2.client.rendering.WhiteTexture; | |
import rcteam.rc2.rollercoaster.ThemeParkLogo; | |
import java.awt.*; | |
import java.awt.image.BufferedImage; | |
public class ClientProxy extends CommonProxy { | |
public static int trackRenderId = -1; | |
@Override | |
public void initRenderers() { | |
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTrack.class, new TileEntityTrackRenderer()); | |
RC2Blocks.trackMap.forEach((categoryEnum, blockTrack) -> MinecraftForgeClient.registerItemRenderer(Item.getItemFromBlock(blockTrack), new ItemTrackRenderer())); | |
ThemeParkLogo.init(); | |
MinecraftForge.EVENT_BUS.register(new GuiThemeParkOverlay(Minecraft.getMinecraft())); | |
MinecraftForge.EVENT_BUS.register(WhiteTexture.instance); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[16:49:33] [Client thread/WARN]: Failed to load texture: minecraft:white | |
java.io.FileNotFoundException: minecraft:white | |
at net.minecraft.client.resources.FallbackResourceManager.getResource(FallbackResourceManager.java:65) ~[FallbackResourceManager.class:?] | |
at net.minecraft.client.resources.SimpleReloadableResourceManager.getResource(SimpleReloadableResourceManager.java:67) ~[SimpleReloadableResourceManager.class:?] | |
at net.minecraft.client.renderer.texture.SimpleTexture.loadTexture(SimpleTexture.java:35) ~[SimpleTexture.class:?] | |
at net.minecraft.client.renderer.texture.TextureManager.loadTexture(TextureManager.java:89) [TextureManager.class:?] | |
at net.minecraft.client.renderer.texture.TextureManager.bindTexture(TextureManager.java:45) [TextureManager.class:?] | |
at rcteam.rc2.util.OBJModel$Group.render(OBJModel.java:832) [OBJModel$Group.class:?] | |
at rcteam.rc2.util.OBJModel.lambda$renderAll$0(OBJModel.java:216) [OBJModel.class:?] | |
at rcteam.rc2.util.OBJModel$$Lambda$15/1751670624.accept(Unknown Source) [OBJModel.class:?] | |
at java.util.HashMap.forEach(HashMap.java:1280) [?:1.8.0_45] | |
at rcteam.rc2.util.OBJModel.renderAll(OBJModel.java:216) [OBJModel.class:?] | |
at rcteam.rc2.client.rendering.TileEntityTrackRenderer.renderTileEntityAt(TileEntityTrackRenderer.java:28) [TileEntityTrackRenderer.class:?] | |
at net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.renderTileEntityAt(TileEntityRendererDispatcher.java:141) [TileEntityRendererDispatcher.class:?] | |
at net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher.renderTileEntity(TileEntityRendererDispatcher.java:126) [TileEntityRendererDispatcher.class:?] | |
at net.minecraft.client.renderer.RenderGlobal.renderEntities(RenderGlobal.java:539) [RenderGlobal.class:?] | |
at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1300) [EntityRenderer.class:?] | |
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1087) [EntityRenderer.class:?] | |
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1068) [Minecraft.class:?] | |
at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?] | |
at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?] | |
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45] | |
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45] | |
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45] | |
at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45] | |
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?] | |
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?] | |
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?] | |
at GradleStart.main(Unknown Source) [start/:?] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rcteam.rc2.util; | |
import com.google.common.collect.ImmutableList; | |
import com.google.common.collect.Lists; | |
import net.minecraft.client.Minecraft; | |
import net.minecraft.client.renderer.Tessellator; | |
import net.minecraft.client.renderer.texture.TextureMap; | |
import net.minecraft.util.ResourceLocation; | |
import net.minecraftforge.client.model.IModelCustom; | |
import net.minecraftforge.client.model.ModelFormatException; | |
import rcteam.rc2.client.rendering.WhiteTexture; | |
import javax.vecmath.Vector2f; | |
import javax.vecmath.Vector3f; | |
import javax.vecmath.Vector4f; | |
import java.io.*; | |
import java.util.*; | |
public class OBJModel implements IModelCustom { | |
private String filePath; | |
private InputStreamReader objStream; | |
private BufferedReader objReader; | |
// private ResourceLocation objFrom; | |
// private File objFrom; | |
public MaterialLibrary materialLibrary = new MaterialLibrary(); | |
private List<String> groupList = new ArrayList<>(); | |
private List<Vertex> vertices = new ArrayList<>(); | |
private List<Normal> normals = new ArrayList<>(); | |
private List<TextureCoordinate> texCoords = new ArrayList<>(); | |
private float minU = 0f; | |
private float maxU = 1f; | |
private float minV = 0f; | |
private float maxV = 1f; | |
// public OBJModel(ResourceLocation from) throws ModelFormatException { | |
// this.fileName = from.toString(); | |
// this.objFrom = from; | |
// try { | |
// IResource resource = Minecraft.getMinecraft().getResourceManager().getResource(from); | |
// this.objStream = new InputStreamReader(resource.getInputStream(), Charsets.UTF_8); | |
// this.objReader = new BufferedReader(objStream); | |
// parseModel(); | |
// } catch (IOException e) { | |
// throw new ModelFormatException("IO Exception reading model format", e); | |
// } | |
// } | |
public OBJModel(FileInputStream fromStream, String filePath) throws ModelFormatException { | |
// public OBJModel(File from, String fileName) throws ModelFormatException { | |
this.filePath = filePath; | |
// this.objFrom = from; | |
try { | |
// this.objStream = new InputStreamReader(new FileInputStream(from), Charsets.UTF_8); | |
this.objStream = new InputStreamReader(fromStream); | |
this.objReader = new BufferedReader(objStream); | |
parseModel(); | |
} catch (IOException e) { | |
throw new ModelFormatException("IO Exception reading model format", e); | |
} | |
} | |
private void parseModel() throws IOException { | |
String currentLine = ""; | |
Material material = new Material(); | |
int usemtlCounter = 0; | |
for (;;) { | |
currentLine = objReader.readLine(); | |
if (currentLine == null) break; | |
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue; | |
String[] fields = currentLine.split(" ", 2); | |
String key = fields[0]; | |
String data = fields[1]; | |
if (key.equalsIgnoreCase("mtllib")) { | |
FileInputStream mtl = new FileInputStream(new File(this.filePath + "/" + data)); //TODO: allow referencing models outside of the directory? that aren't named the same? | |
this.materialLibrary.parseMaterials(mtl); | |
} else if (key.equalsIgnoreCase("usemtl")) { | |
material = this.materialLibrary.materials.get(data); | |
usemtlCounter++; | |
} else if (key.equalsIgnoreCase("v")) { | |
String[] splitData = data.split(" "); | |
float[] floatSplitData = new float[splitData.length]; | |
for (int i = 0; i < splitData.length; i++) { | |
floatSplitData[i] = Float.parseFloat(splitData[i]); | |
} | |
Vector4f pos = new Vector4f(floatSplitData[0], floatSplitData[1], floatSplitData[2], floatSplitData.length == 4 ? floatSplitData[3] : 1); | |
// Vertex vertex = new Vertex(pos, material); | |
Vertex vertex = new Vertex(pos, material.getName()); | |
this.vertices.add(vertex); | |
} else if (key.equalsIgnoreCase("vn")) { | |
String[] splitData = data.split(" "); | |
float[] floatSplitData = new float[splitData.length]; | |
for (int i = 0; i < splitData.length; i++) { | |
floatSplitData[i] = Float.parseFloat(splitData[i]); | |
} | |
Normal normal = new Normal(new Vector3f(floatSplitData[0], floatSplitData[1], floatSplitData[2])); | |
this.normals.add(normal); | |
} else if (key.equalsIgnoreCase("vt")) { | |
String[] splitData = data.split(" "); | |
float[] floatSplitData = new float[splitData.length]; | |
for (int i = 0; i < splitData.length; i++) { | |
floatSplitData[i] = Float.parseFloat(splitData[i]); | |
} | |
TextureCoordinate texCoord = new TextureCoordinate(new Vector3f(floatSplitData[0], floatSplitData[1], floatSplitData.length == 3 ? floatSplitData[2] : 1)); | |
this.minU = floatSplitData[0] < this.minU ? floatSplitData[0] : this.minU; | |
this.maxU = floatSplitData[0] > this.maxU ? floatSplitData[0] : this.maxU; | |
this.minV = floatSplitData[1] < this.minV ? floatSplitData[1] : this.minV; | |
this.maxV = floatSplitData[1] > this.maxV ? floatSplitData[1] : this.maxV; | |
this.texCoords.add(texCoord); | |
} else if (key.equalsIgnoreCase("f")) { | |
String[] splitSpace = data.split(" "); | |
String[][] splitSlash = new String[splitSpace.length][]; | |
int vert = 0; | |
int norm = 0; | |
int texCoord = 0; | |
List<Vertex> v = new ArrayList<>(splitSpace.length); | |
List<Normal> n = new ArrayList<>(splitSpace.length); | |
List<TextureCoordinate> t = new ArrayList<>(splitSpace.length); | |
for (int i = 0; i < splitSpace.length; i++) { | |
if (splitSpace[i].contains("//")) { | |
splitSlash[i] = splitSpace[i].split("//"); | |
vert = Integer.parseInt(splitSlash[i][0]); | |
vert = vert < 0 ? this.vertices.size() - 1 : vert - 1; | |
norm = Integer.parseInt(splitSlash[i][1]); | |
norm = norm < 0 ? this.normals.size() - 1 : norm - 1; | |
v.add(this.vertices.get(vert)); | |
n.add(this.normals.get(norm)); | |
} else if (splitSpace[i].contains("/")) { | |
splitSlash[i] = splitSpace[i].split("/"); | |
vert = Integer.parseInt(splitSlash[i][0]); | |
vert = vert < 0 ? this.vertices.size() - 1 : vert - 1; | |
texCoord = Integer.parseInt(splitSlash[i][1]); | |
texCoord = texCoord < 0 ? this.texCoords.size() - 1 : texCoord - 1; | |
if (splitSlash[i].length > 2) { | |
norm = Integer.parseInt(splitSlash[i][2]); | |
norm = norm < 0 ? this.normals.size() - 1 : norm - 1; | |
} | |
v.add(this.vertices.get(vert)); | |
t.add(this.texCoords.get(texCoord)); | |
if (splitSlash[i].length > 2) n.add(this.normals.get(norm)); | |
} else { | |
splitSlash[i] = splitSpace[i].split(""); | |
vert = Integer.parseInt(splitSlash[i][0]); | |
vert = vert < 0 ? this.vertices.size() - 1 : vert - 1; | |
v.add(this.vertices.get(vert)); | |
} | |
} | |
Vertex[] va = new Vertex[v.size()]; | |
v.toArray(va); | |
Normal[] na = new Normal[n.size()]; | |
n.toArray(na); | |
TextureCoordinate[] ta = new TextureCoordinate[t.size()]; | |
t.toArray(ta); | |
Face face = new Face(va, na, ta, material.getName()); | |
if (usemtlCounter < this.vertices.size()) { //if the model doesn't use per-vertex coloring then override the vertex material with the face's material | |
for (Vertex vertex : face.getVertices()) { | |
vertex.setMaterialName(material.getName()); | |
} | |
} | |
if (groupList.isEmpty()) { | |
if (this.materialLibrary.getGroups().containsKey(Group.DEFAULT_NAME)) { | |
this.materialLibrary.getGroups().get(Group.DEFAULT_NAME).addFace(face); | |
} else { | |
Group def = new Group(Group.DEFAULT_NAME, null); | |
def.addFace(face); | |
this.materialLibrary.getGroups().put(Group.DEFAULT_NAME, def); | |
} | |
} else { | |
for (String s : groupList) { | |
if (this.materialLibrary.getGroups().containsKey(s)) { | |
this.materialLibrary.getGroups().get(s).addFace(face); | |
} else { | |
Group g = new Group(s, null); | |
g.addFace(face); | |
this.materialLibrary.getGroups().put(s, g); | |
} | |
} | |
} | |
} else if (key.equalsIgnoreCase("g") || key.equalsIgnoreCase("o")) { | |
groupList.clear(); | |
if (key.equalsIgnoreCase("g")) { | |
String[] splitSpace = data.split(" "); | |
for (String s : splitSpace) { | |
groupList.add(s); | |
} | |
} else { | |
groupList.add(data); | |
} | |
} | |
} | |
this.materialLibrary.setUVBounds(minU, maxU, minV, maxV); | |
} | |
@Override | |
public String getType() { | |
return "obj"; | |
} | |
@Override | |
public void renderAll() { | |
this.materialLibrary.getGroups().forEach((s, group) -> group.render(this)); | |
} | |
@Override | |
public void renderOnly(String... groupNames) { | |
Lists.newArrayList(groupNames).forEach(s -> renderPart(s)); | |
} | |
@Override | |
public void renderPart(String partName) { | |
this.materialLibrary.getGroups().get(partName).render(this); | |
} | |
@Override | |
public void renderAllExcept(String... excludedGroupNames) { | |
this.materialLibrary.getGroups().values().stream().filter(group -> !Lists.newArrayList(excludedGroupNames).contains(group.getName())).forEach(group1 -> group1.render(this)); | |
} | |
public MaterialLibrary getMaterialLibrary() { | |
return this.materialLibrary; | |
} | |
public static class MaterialLibrary { | |
private Map<String, Material> materials = new HashMap<>(); | |
private Map<String, Group> groups = new HashMap<>(); | |
private InputStreamReader mtlStream; | |
private BufferedReader mtlReader; | |
private float minU = 0f; | |
private float maxU = 1f; | |
private float minV = 0f; | |
private float maxV = 1f; | |
public MaterialLibrary() { | |
this.groups.put(Group.DEFAULT_NAME, new Group(Group.DEFAULT_NAME, null)); | |
} | |
public float getMinU() { | |
return this.minU; | |
} | |
public float getMaxU() { | |
return this.maxU; | |
} | |
public float getMinV() { | |
return this.minV; | |
} | |
public float getMaxV() { | |
return this.maxV; | |
} | |
public void setUVBounds(float minU, float maxU, float minV, float maxV) { | |
this.minU = minU; | |
this.maxU = maxU; | |
this.minV = minV; | |
this.maxV = maxV; | |
} | |
public Map<String, Group> getGroups() { | |
return this.groups; | |
} | |
public List<Group> getGroupsContainingFace(Face face) { | |
List<Group> groups = new ArrayList<>(); | |
for (Group group : this.groups.values()) { | |
if (group.faces.contains(face)) groups.add(group); | |
} | |
return groups; | |
} | |
public void changeMaterialColor(String name, int color) { | |
Vector4f colorVec = new Vector4f((color >> 16 & 255) / 255, (color >> 8 & 255) / 255, (color & 255) / 255, (color >> 24 & 255) / 255); | |
this.materials.get(name).setColor(colorVec); | |
} | |
public Material getMaterial(String name) { | |
return this.materials.get(name); | |
} | |
public ImmutableList<String> getMaterialNames() { | |
return ImmutableList.copyOf(this.materials.keySet()); | |
} | |
public void parseMaterials(FileInputStream fromStream) throws IOException { | |
// public void parseMaterials(String path, File from) throws IOException { | |
this.materials.clear(); | |
boolean hasSetTexture = false; | |
boolean hasSetColor = false; | |
// String domain = from.getResourceDomain(); | |
// mtlStream = new InputStreamReader(Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(domain, path)).getInputStream(), Charsets.UTF_8); | |
// mtlReader = new BufferedReader(mtlStream); | |
// this.mtlStream = new InputStreamReader(newFileInputStream(from), Charsets.UTF_8); | |
this.mtlStream = new InputStreamReader(fromStream); | |
this.mtlReader = new BufferedReader(this.mtlStream); | |
String currentLine = ""; | |
Material material = new Material(); | |
material.setName(Material.WHITE_NAME); | |
material.setTexture(Texture.white); | |
this.materials.put(Material.WHITE_NAME, material); | |
this.materials.put(Material.DEFAULT_NAME, new Material(Texture.white)); | |
for (;;) { | |
currentLine = mtlReader.readLine(); | |
if (currentLine == null) break; | |
if (currentLine.isEmpty() || currentLine.startsWith("#")) continue; | |
String[] fields = currentLine.split(" ", 2); | |
String key = fields[0]; | |
String data = fields[1]; | |
if (key.equalsIgnoreCase("newmtl")) { | |
hasSetColor = false; | |
hasSetTexture = false; | |
material = new Material(); | |
material.setName(data); | |
this.materials.put(data, material); | |
} else if (key.equalsIgnoreCase("Ka") || key.equalsIgnoreCase("Kd") || key.equalsIgnoreCase("Ks")) { | |
if (key.equalsIgnoreCase("Kd") || !hasSetColor) { | |
String[] rgbStrings = data.split(" ", 3); | |
Vector4f color = new Vector4f(Float.parseFloat(rgbStrings[0]), Float.parseFloat(rgbStrings[1]), Float.parseFloat(rgbStrings[2]), 1.0f); | |
hasSetColor = true; | |
material.setColor(color); | |
} | |
} else if (key.equalsIgnoreCase("map_Ka") || key.equalsIgnoreCase("map_Kd") || key.equalsIgnoreCase("map_Ks")) { | |
if (key.equalsIgnoreCase("map_Kd") || !hasSetTexture) { | |
if (data.contains(" ")) { | |
String[] mapStrings = data.split(" "); | |
String texturePath = mapStrings[mapStrings.length - 1]; | |
Texture texture = new Texture(texturePath); | |
hasSetTexture = true; | |
material.setTexture(texture); | |
} else { | |
Texture texture = new Texture(data); | |
hasSetTexture = true; | |
material.setTexture(texture); | |
} | |
} | |
} | |
} | |
} | |
} | |
public static class Material { | |
public static final String WHITE_NAME = "OBJModel.white.Texture.Name"; | |
public static final String DEFAULT_NAME = "OBJModel.Default.Texture.Name"; | |
private Vector4f color; | |
private Texture texture = Texture.white; | |
private String name = DEFAULT_NAME; | |
public Material() { | |
this(new Vector4f(1f, 1f, 1f, 1f)); | |
} | |
public Material(Vector4f color) { | |
this(color, Texture.white, WHITE_NAME); | |
} | |
public Material(Texture texture) { | |
this(new Vector4f(1f, 1f, 1f, 1f), texture, DEFAULT_NAME); | |
} | |
public Material(Vector4f color, Texture texture, String name) { | |
this.color = color; | |
this.texture = texture; | |
this.name = name != null ? name : DEFAULT_NAME; | |
} | |
public void setName(String name) { | |
this.name = name != null ? name : DEFAULT_NAME; | |
} | |
public String getName() { | |
return this.name; | |
} | |
public void setColor(Vector4f color) { | |
this.color = color; | |
} | |
public Vector4f getColor() { | |
return this.color; | |
} | |
public void setTexture(Texture texture) { | |
this.texture = texture; | |
} | |
public Texture getTexture() { | |
return this.texture; | |
} | |
public boolean isWhite() { | |
return this.texture.equals(Texture.white); | |
} | |
@Override | |
public String toString() | |
{ | |
StringBuilder builder = new StringBuilder(String.format("%nMaterial:%n")); | |
builder.append(String.format(" Name: %s%n", this.name)); | |
builder.append(String.format(" Color: %s%n", this.color.toString())); | |
builder.append(String.format(" Is white: %b%n", this.isWhite())); | |
return builder.toString(); | |
} | |
} | |
public static class Texture { | |
public static Texture white = new Texture(WhiteTexture.loc.getResourcePath(), new Vector2f(0, 0), new Vector2f(1, 1), 0); | |
private String path; | |
private Vector2f position; | |
private Vector2f scale; | |
private float rotation; | |
public Texture(String path) { | |
this(path, new Vector2f(0, 0), new Vector2f(1, 1), 0); | |
} | |
public Texture(String path, Vector2f position, Vector2f scale, float rotation) { | |
this.path = path; | |
this.position = position; | |
this.scale = scale; | |
this.rotation = rotation; | |
} | |
public ResourceLocation getTextureLocation() { | |
return new ResourceLocation(this.path); | |
} | |
public void setPath(String path) { | |
this.path = path; | |
} | |
public String getPath() { | |
return this.path; | |
} | |
public void setPosition(Vector2f position) { | |
this.position = position; | |
} | |
public Vector2f getPosition() { | |
return this.position; | |
} | |
public void setRotation(float rotation) { | |
this.rotation = rotation; | |
} | |
public float getRotation() { | |
return this.rotation; | |
} | |
} | |
public static class Face { | |
private Vertex[] verts = new Vertex[4]; | |
private Normal[] norms = new Normal[4]; | |
private TextureCoordinate[] texCoords = new TextureCoordinate[4]; | |
private String materialName = Material.DEFAULT_NAME; | |
public Face(Vertex[] verts) { | |
this(verts, null, null); | |
} | |
public Face(Vertex[] verts, Normal[] norms) { | |
this(verts, norms, null); | |
} | |
public Face(Vertex[] verts, TextureCoordinate[] texCoords) { | |
this(verts, null, texCoords); | |
} | |
public Face(Vertex[] verts, Normal[] norms, TextureCoordinate[] texCoords) { | |
this(verts, norms, texCoords, Material.DEFAULT_NAME); | |
} | |
public Face(Vertex[] verts, Normal[] norms, TextureCoordinate[] texCoords, String materialName) { | |
this.verts = verts; | |
this.verts = this.verts != null && this.verts.length > 0 ? this.verts : null; | |
this.norms = norms; | |
this.norms = this.norms != null && this.norms.length > 0 ? this.norms : null; | |
this.texCoords = texCoords; | |
this.texCoords = this.texCoords != null && this.texCoords.length > 0 ? this.texCoords : null; | |
setMaterialName(materialName); | |
ensureQuads(); | |
} | |
private void ensureQuads() { | |
if (this.verts != null && this.verts.length == 3) { | |
this.verts = new Vertex[] {this.verts[0], this.verts[1], this.verts[2], this.verts[2]}; | |
} | |
if (this.norms != null && this.norms.length == 3) { | |
this.norms = new Normal[] {this.norms[0], this.norms[1], this.norms[2], this.norms[2]}; | |
} | |
if (this.texCoords != null && this.texCoords.length == 3) { | |
this.texCoords = new TextureCoordinate[] {this.texCoords[0], this.texCoords[1], this.texCoords[2], this.texCoords[2]}; | |
} | |
} | |
public void setMaterialName(String materialName) { | |
this.materialName = materialName != null && !materialName.isEmpty() ? materialName : this.materialName; | |
} | |
public String getMaterialName() { | |
return this.materialName; | |
} | |
public boolean setVertices(Vertex[] verts) { | |
if (verts == null) return false; | |
else this.verts = verts; | |
return true; | |
} | |
public Vertex[] getVertices() { | |
return this.verts; | |
} | |
public boolean setNormals(Normal[] norms) { | |
if (norms == null) return false; | |
else this.norms = norms; | |
return true; | |
} | |
public Normal[] getNormals() { | |
return this.norms; | |
} | |
public boolean setTextureCoordinates(TextureCoordinate[] texCoords) { | |
if (texCoords == null) return false; | |
else this.texCoords = texCoords; | |
return true; | |
} | |
public TextureCoordinate[] getTextureCoordinates() { | |
return this.texCoords; | |
} | |
public boolean areUVsNormalized() { | |
for (TextureCoordinate t : this.texCoords) { | |
float[] position = new float[2]; | |
t.getPosition().get(position); | |
if (!(position[0] >= 0.0f && position[0] <= 1.0f && position[1] >= 0.0f && position[1] <= 1.0f)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
// public Face bake(TRSRTransformation transform) | |
// { | |
// Matrix4f m = transform.getMatrix(); | |
// Vertex[] vertices = new Vertex[verts.length]; | |
// Normal[] normals = norms != null ? new Normal[norms.length] : null; | |
// TextureCoordinate[] textureCoords = texCoords != null ? new TextureCoordinate[texCoords.length] : null; | |
// | |
// for (int i = 0; i < verts.length; i++) | |
// { | |
// m = transform.getMatrix(); | |
// Vertex v = verts[i]; | |
// Normal n = norms != null ? norms[i] : null; | |
// TextureCoordinate t = texCoords != null ? texCoords[i] : null; | |
// | |
// Vector4f pos = new Vector4f(v.getPosition()), newPos = new Vector4f(); | |
// pos.w = 1; | |
// m.transform(pos, newPos); | |
// Vector4f rPos = new Vector4f(newPos.x, newPos.y, newPos.z, newPos.w); | |
// vertices[i] = new Vertex(rPos, v.getMaterial()); | |
// | |
// if (n != null) | |
// { | |
// m.invert(); | |
// m.transpose(); | |
// Vector4f normal = new Vector4f(n.getNormal()), 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 | |
// if (t != null) textureCoords[i] = t; | |
// } | |
// return new Face(vertices, normals, textureCoords, this.materialName); | |
// } | |
public Normal getNormal() { | |
if (norms == null) { // use vertices to calculate normal | |
Vector3f v1 = new Vector3f(this.verts[0].getPosition().x, this.verts[0].getPosition().y, this.verts[0].getPosition().z); | |
Vector3f v2 = new Vector3f(this.verts[1].getPosition().x, this.verts[1].getPosition().y, this.verts[1].getPosition().z); | |
Vector3f v3 = new Vector3f(this.verts[2].getPosition().x, this.verts[2].getPosition().y, this.verts[2].getPosition().z); | |
Vector3f v4 = this.verts.length > 3 ? new Vector3f(this.verts[3].getPosition().x, this.verts[3].getPosition().y, this.verts[3].getPosition().z) : null; | |
if (v4 == null) { | |
Vector3f v2c = new Vector3f(v2.x, v2.y, v2.z); | |
Vector3f v1c = new Vector3f(v1.x, v1.y, v1.z); | |
v1c.sub(v2c); | |
Vector3f v3c = new Vector3f(v3.x, v3.y, v3.z); | |
v3c.sub(v2c); | |
Vector3f c = new Vector3f(); | |
c.cross(v1c, v3c); | |
c.normalize(); | |
Normal normal = new Normal(c); | |
return normal; | |
} else { | |
Vector3f v2c = new Vector3f(v2.x, v2.y, v2.z); | |
Vector3f v1c = new Vector3f(v1.x, v1.y, v1.z); | |
v1c.sub(v2c); | |
Vector3f v3c = new Vector3f(v3.x, v3.y, v3.z); | |
v3c.sub(v2c); | |
Vector3f c = new Vector3f(); | |
c.cross(v1c, v3c); | |
c.normalize(); | |
v1c = new Vector3f(v1.x, v1.y, v1.z); | |
v3c = new Vector3f(v3.x, v3.y, v3.z); | |
Vector3f v4c = new Vector3f(v4.x, v4.y, v4.z); | |
v1c.sub(v4c); | |
v3c.sub(v4c); | |
Vector3f d = new Vector3f(); | |
d.cross(v1c, v3c); | |
d.normalize(); | |
Vector3f avg = new Vector3f(); | |
avg.x = (c.x + d.x) * 0.5f; | |
avg.y = (c.y + d.y) * 0.5f; | |
avg.z = (c.z + d.z) * 0.5f; | |
avg.normalize(); | |
Normal normal = new Normal(avg); | |
return normal; | |
} | |
} else { // use normals to calculate normal | |
Vector3f n1 = this.norms[0].getNormal(); | |
Vector3f n2 = this.norms[1].getNormal(); | |
Vector3f n3 = this.norms[2].getNormal(); | |
Vector3f n4 = this.norms.length > 3 ? this.norms[3].getNormal() : null; | |
if (n4 == null) { | |
Vector3f n2c = new Vector3f(n2.x, n2.y, n2.z); | |
Vector3f n1c = new Vector3f(n1.x, n1.y, n1.z); | |
n1c.sub(n2c); | |
Vector3f n3c = new Vector3f(n3.x, n3.y, n3.z); | |
n3c.sub(n2c); | |
Vector3f c = new Vector3f(); | |
c.cross(n1c, n3c); | |
c.normalize(); | |
Normal normal = new Normal(c); | |
return normal; | |
} else { | |
Vector3f n2c = new Vector3f(n2.x, n2.y, n2.z); | |
Vector3f n1c = new Vector3f(n1.x, n1.y, n1.z); | |
n1c.sub(n2c); | |
Vector3f n3c = new Vector3f(n3.x, n3.y, n3.z); | |
n3c.sub(n2c); | |
Vector3f c = new Vector3f(); | |
c.cross(n1c, n3c); | |
c.normalize(); | |
n1c = new Vector3f(n1.x, n1.y, n1.z); | |
n3c = new Vector3f(n3.x, n3.y, n3.z); | |
Vector3f n4c = new Vector3f(n4.x, n4.y, n4.z); | |
n1c.sub(n4c); | |
n3c.sub(n4c); | |
Vector3f d = new Vector3f(); | |
d.cross(n1c, n3c); | |
d.normalize(); | |
Vector3f avg = new Vector3f(); | |
avg.x = (c.x + d.x) * 0.5f; | |
avg.y = (c.y + d.y) * 0.5f; | |
avg.z = (c.z + d.z) * 0.5f; | |
avg.normalize(); | |
Normal normal = new Normal(avg); | |
return normal; | |
} | |
} | |
} | |
} | |
public static class Vertex { | |
private Vector4f position; | |
// private Material material = new Material(); | |
private String materialName = Material.DEFAULT_NAME; | |
public Vertex(Vector4f position, String materialName) { | |
this.position = position; | |
this.materialName = materialName; | |
} | |
// public Vertex(Vector4f position, Material material) { | |
// this.position = position; | |
// this.material = material; | |
// } | |
public void setPos(Vector4f position) { | |
this.position = position; | |
} | |
public Vector4f getPosition() { | |
return this.position; | |
} | |
public void setMaterialName(String materialName) { | |
this.materialName = materialName; | |
} | |
public String getMaterialName() { | |
return this.materialName; | |
} | |
// public void setMaterial(Material material) { | |
// this.material = material; | |
// } | |
// | |
// public Material getMaterial() { | |
// return this.material; | |
// } | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append(String.format("v:%n")); | |
builder.append(String.format(" position: %s %s %s%n", position.x, position.y, position.z)); | |
builder.append(String.format(" material: %s", materialName)); | |
// builder.append(String.format(" material: %s %s %s %s %s%n", material.getColor().x, material.getColor().y, material.getColor().z, material.getColor().w)); | |
return builder.toString(); | |
} | |
} | |
public static class Normal { | |
private Vector3f normal; | |
public Normal(Vector3f normal) { | |
this.normal = normal; | |
} | |
public void setNormal(Vector3f normal) { | |
this.normal = normal; | |
} | |
public Vector3f getNormal() { | |
return this.normal; | |
} | |
} | |
public static class TextureCoordinate { | |
private Vector3f position; | |
public TextureCoordinate(Vector3f position) { | |
this.position = position; | |
} | |
public void setPosition(Vector3f position) { | |
this.position = position; | |
} | |
public Vector3f getPosition() { | |
return this.position; | |
} | |
} | |
public static class Group { | |
public static final String DEFAULT_NAME = "OBJModel.Default.Element.Name"; | |
public static final String ALL = "OBJModel.Group.All.Key"; | |
public static final String ALL_EXCEPT = "OBJModel.Group.All.Except.Key"; | |
private String name = DEFAULT_NAME; | |
private LinkedHashSet<Face> faces = new LinkedHashSet<Face>(); | |
public Group(String name, LinkedHashSet<Face> faces) { | |
this.name = name != null ? name : DEFAULT_NAME; | |
this.faces = faces == null ? new LinkedHashSet<>() : faces; | |
} | |
public String getName() { | |
return this.name; | |
} | |
public LinkedHashSet<Face> getFaces() { | |
return this.faces; | |
} | |
public void setFaces(LinkedHashSet<Face> faces) { | |
this.faces = faces; | |
} | |
public void addFace(Face face) { | |
this.faces.add(face); | |
} | |
public void addFaces(List<Face> faces) { | |
this.faces.addAll(faces); | |
} | |
public List<String> getFaceMaterialNames() { | |
List<String> names = Lists.newArrayList(); | |
this.faces.forEach(face -> names.add(face.getMaterialName())); | |
return names; | |
} | |
public List<String> getVertexMaterialNames() { | |
List<String> names = Lists.newArrayList(); | |
this.faces.forEach(face -> Arrays.asList(face.getVertices()).forEach(vertex -> names.add(vertex.getMaterialName()))); | |
return names; | |
} | |
public void render(OBJModel model) { | |
// RC2.logger.info("RENDERING"); | |
Tessellator tessellator = Tessellator.instance; | |
tessellator.startDrawingQuads(); | |
// RC2.logger.info(String.format("white texture null: %b", Minecraft.getMinecraft().getTextureMapBlocks().getTextureExtry(WhiteTexture.loc.toString()) == null)); | |
for (Face face : this.faces) { | |
Minecraft.getMinecraft().getTextureManager().bindTexture(model.materialLibrary.getMaterial(face.getMaterialName()).getTexture().getTextureLocation()); | |
// Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture); | |
Normal normal = face.getNormal(); | |
if (!model.getMaterialLibrary().getMaterial(face.getMaterialName()).isWhite()) { | |
Vector4f color = model.getMaterialLibrary().getMaterial(face.getMaterialName()).getColor(); | |
tessellator.setColorRGBA_F(color.x, color.y, color.z, color.w); | |
} | |
for (int i = 0; i < face.getVertices().length; i++) { | |
// RC2.logger.info("RENDERING"); | |
// tessellator.startDrawingQuads(); | |
if (face.getNormals() != null && face.getNormals().length > 0) { | |
tessellator.setNormal(face.getNormals()[i].getNormal().x, face.getNormals()[i].getNormal().y, face.getNormals()[i].getNormal().z); | |
} else { | |
tessellator.setNormal(normal.getNormal().x, normal.getNormal().y, normal.getNormal().z); | |
} | |
if (face.getTextureCoordinates() != null && face.getTextureCoordinates().length > 0) { | |
tessellator.addVertexWithUV(face.getVertices()[i].getPosition().x, face.getVertices()[i].getPosition().y, face.getVertices()[i].getPosition().z, face.getTextureCoordinates()[i].getPosition().x, face.getTextureCoordinates()[i].getPosition().y); | |
} else { | |
tessellator.addVertex(face.getVertices()[i].getPosition().x, face.getVertices()[i].getPosition().y, face.getVertices()[i].getPosition().z); | |
} | |
if (model.getMaterialLibrary().getMaterial(face.getMaterialName()).isWhite()) { | |
Vector4f color = model.getMaterialLibrary().getMaterial(face.getVertices()[i].getMaterialName()).getColor(); | |
tessellator.setColorRGBA_F(color.x, color.y, color.z, color.w); | |
} | |
// tessellator.draw(); | |
// tessellator.setColorRGBA_F(face.getVertices()[i].getMaterial().getColor().x, face.getVertices()[i].getMaterial().getColor().y, face.getVertices()[i].getMaterial().getColor().z, face.getVertices()[i].getMaterial().getColor().w); | |
} | |
// tessellator.draw(); | |
} | |
tessellator.draw(); | |
Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rcteam.rc2.client.rendering; | |
import cpw.mods.fml.common.eventhandler.SubscribeEvent; | |
import net.minecraft.client.Minecraft; | |
import net.minecraft.client.renderer.texture.TextureAtlasSprite; | |
import net.minecraft.client.renderer.texture.TextureMap; | |
import net.minecraft.client.resources.IResourceManager; | |
import net.minecraft.util.ResourceLocation; | |
import net.minecraftforge.client.event.TextureStitchEvent; | |
import java.awt.*; | |
import java.awt.image.BufferedImage; | |
public class WhiteTexture extends TextureAtlasSprite { | |
public static ResourceLocation loc = new ResourceLocation("white"); | |
public static WhiteTexture instance = new WhiteTexture(); | |
protected WhiteTexture() { | |
super(loc.toString()); | |
} | |
@Override | |
public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { | |
return true; | |
} | |
@Override | |
public boolean load(IResourceManager manager, ResourceLocation location) { | |
BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); | |
Graphics2D graphics = image.createGraphics(); | |
graphics.setBackground(Color.WHITE); | |
graphics.clearRect(0, 0, 16, 16); | |
BufferedImage[] images = new BufferedImage[Minecraft.getMinecraft().gameSettings.mipmapLevels + 1]; | |
images[0] = image; | |
loadSprite(images, null, true); | |
return false; | |
} | |
@SubscribeEvent | |
public void register(TextureStitchEvent.Pre event) { | |
event.map.setTextureEntry(WhiteTexture.loc.toString(), WhiteTexture.instance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment