import java.io.*; import java.util.Vector; import java.util.StringTokenizer; public class FloatParser3 { public static void main (String [] args) throws Exception { FileOutputStream out_v = new FileOutputStream("vertex_rom.v"); FileOutputStream out_f = new FileOutputStream("face_rom.v"); PrintStream ver = new PrintStream(out_v); PrintStream f = new PrintStream(out_f); ver.println("module Vertex_ROM (vertex_index_0, vertex_index_1, vertex_index_2, vertex1, vertex2, vertex3, color1, color2, color3, normal1, normal2, normal3);\n"); ver.print("input [11:0] vertex_index_0, vertex_index_1, vertex_index_2;\noutput reg[53:0] vertex1, vertex2, vertex3;\noutput reg[13:0] color1, color2, color3;\noutput reg[53:0] normal1, normal2, normal3;\n\nalways @(vertex_index_0 or vertex_index_1 or vertex_index_2)\nbegin"); BufferedReader reader = new BufferedReader(new FileReader("bunny500_norms.msh")); String currentLine = reader.readLine(); float[] currentVertex = new float[3]; int currentExponent = 0; String[] vertex = new String[3]; String exponent = ""; int exponentLength = 0; int vertexLength = 0; int numberVertices = 0; String twelvebitI = ""; int twelvebitILength = 0; Vector vertices = new Vector(); Vector faces = new Vector(); Vector normals = new Vector(); Vector colors = new Vector(); numberVertices = Integer.parseInt(currentLine); vertices.setSize(numberVertices); currentLine = reader.readLine(); faces.setSize(Integer.parseInt(currentLine)); normals.setSize(numberVertices); colors.setSize(numberVertices); reader.readLine(); String thisLine = ""; StringTokenizer tokens; for (int i = 0; i < vertices.size(); i++) { vertices.setElementAt(new ThreeTupleFloat(Float.parseFloat(reader.readLine()), Float.parseFloat(reader.readLine()), Float.parseFloat(reader.readLine())), i); } reader.readLine(); for (int i = 0; i < faces.size(); i++) { thisLine = reader.readLine(); tokens = new StringTokenizer(thisLine); faces.setElementAt(new ThreeTupleInt(Integer.parseInt(tokens.nextToken()), Integer.parseInt(reader.readLine()), Integer.parseInt(reader.readLine())), i); //thisLine = tokens.nextToken(); //colors.setElementAt(thisLine, faces.elementAt(i).x); //colors.setElementAt(thisLine, faces.elementAt(i).y); //colors.setElementAt(thisLine, faces.elementAt(i).z); } reader.readLine(); for (int i = 0; i < normals.size(); i++) { normals.setElementAt(new ThreeTupleFloat(Float.parseFloat(reader.readLine()), Float.parseFloat(reader.readLine()), Float.parseFloat(reader.readLine())), i); } for (int k = 0; k < 3; k++) { ver.println("\n\tcase(vertex_index_" + k + ")"); for (int i = 0; i < vertices.size(); i++) { twelvebitI = Integer.toBinaryString(i); twelvebitILength = twelvebitI.length(); for (int j = 0; j < 12 - twelvebitILength; j++) twelvebitI = "0" + twelvebitI; ver.print("\t\t12'b" + twelvebitI + ": begin vertex" + (k+1) + " = 54'b"); currentVertex[0] = vertices.elementAt(i).x; currentVertex[1] = vertices.elementAt(i).y; currentVertex[2] = vertices.elementAt(i).z; /* for bunny500_normals.msh */ //make 4x bigger in all directions currentVertex[0] *= 4; currentVertex[1] *= 4; currentVertex[2] *= 4; for (int j = 0; j < 3; j++) { if (currentVertex[j] == 0) { ver.print("000000000000000000"); } else if (currentVertex[j] < 0) { if (currentVertex[j] > -0.5f) { while (currentVertex[j] > -0.5f) { currentVertex[j] *= 2.0f; currentExponent--; } } else { while ( currentVertex[j] <= -1 ) { currentVertex[j] /= 2.0f; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; ver.print("1" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } else { if (currentVertex[j] < 0.5f) { while (currentVertex[j] < 0.5f) { currentVertex[j] *= 2.0f; currentExponent-=1; } } else { //exponent while ( currentVertex[j] >= 1 ) { currentVertex[j] /= 2.0d; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; ver.print("0" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } } ver.print("; color" + (k+1) + " = 14'b00000000011111" + /*colors.elementAt(i) +*/ "; "); ver.print ("normal" + (k+1) + " = 54'b"); currentVertex[0] = normals.elementAt(i).x; currentVertex[1] = normals.elementAt(i).y; currentVertex[2] = normals.elementAt(i).z; for (int j = 0; j < 3; j++) { if (currentVertex[j] == 0) { ver.print("000000000000000000"); } else if (currentVertex[j] < 0) { if (currentVertex[j] > -0.5f) { while (currentVertex[j] > -0.5f) { currentVertex[j] *= 2.0f; currentExponent--; } } else { while ( currentVertex[j] <= -1 ) { currentVertex[j] /= 2.0f; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; ver.print("1" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } else { if (currentVertex[j] < 0.5f) { while (currentVertex[j] < 0.5f) { currentVertex[j] *= 2.0f; currentExponent--; } } else { //exponent while ( currentVertex[j] >= 1 ) { currentVertex[j] /= 2.0d; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; ver.print("0" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } } ver.println("; end"); } ver.println("\t\tdefault: begin vertex" + (k+1) + " = 54'b0; color" + (k+1) + " = 14'b00000000011111; normal" + (k+1) + " = 54'b0; end\n\tendcase"); } ver.println("end\nendmodule"); f.println("module Face_ROM (address, constants, triangle_indices, position);\n\ninput [11:0] address;\ninput [2:0] position;\noutput reg [35:0] triangle_indices;\noutput reg [53:0] constants;\n\n"); f.println("always @(address)\nbegin\n\tcase(address)"); for (int i = 0; i < faces.size(); i++) { twelvebitI = Integer.toBinaryString(i); twelvebitILength = twelvebitI.length(); for (int j = 0; j < 12 - twelvebitILength; j++) twelvebitI = "0" + twelvebitI; f.print("\t\t12'b" + twelvebitI + ": begin case(position) "); for (int k = 0; k < 8; k++) { f.print(k + ": begin constants = 54'b"); //calculate constants and output them float y0, y1, y2, x0, x1, x2; //float f12, f20, f01; these will be represented in currentVertex array ThreeTupleFloat a = vertices.elementAt(faces.elementAt(i).x); ThreeTupleFloat b = vertices.elementAt(faces.elementAt(i).y); ThreeTupleFloat c = vertices.elementAt(faces.elementAt(i).z); ThreeTupleFloat e = new ThreeTupleFloat(0,0,0); ThreeTupleFloat g = new ThreeTupleFloat(0,0,0); ThreeTupleFloat u = new ThreeTupleFloat(0,0,0); ThreeTupleFloat v = new ThreeTupleFloat(0,0,0); ThreeTupleFloat w = new ThreeTupleFloat(0,0,0); ThreeTupleFloat t = new ThreeTupleFloat(0,1,0); float x = (float)Math.sin(Math.PI * 2 * (k / 8f)); float z = (float)Math.cos(Math.PI * 2 * (k / 8f)); g.x = -x; g.y = 0; g.z = -z; e.x = 10*x; e.y = 0; e.z = 10*z; w.x = -g.x / magnitude(g); w.y = 0; w.z = -g.z / magnitude(g); u = cross(t, w); u.x /= magnitude(cross(t,w)); u.y /= magnitude(cross(t,w)); u.z /= magnitude(cross(t,w)); v = cross(w, u); x0 = u.x * a.x + u.y * a.y + u.z * a.z - e.x * u.x - e.y * u.y - e.z * u.z; y0 = v.x * a.x + v.y * a.y + v.z * a.z - e.x * v.x - e.y * v.y - e.z * v.z; x1 = u.x * b.x + u.y * b.y + u.z * b.z - e.x * u.x - e.y * u.y - e.z * u.z; y1 = v.x * b.x + v.y * b.y + v.z * b.z - e.x * v.x - e.y * v.y - e.z * v.z; x2 = u.x * c.x + u.y * c.y + u.z * c.z - e.x * u.x - e.y * u.y - e.z * u.z; y2 = v.x * c.x + v.y * c.y + v.z * c.z - e.x * v.x - e.y * v.y - e.z * v.z; y0 = y0 * 64 + 119; y1 = y1 * 64 + 119; y2 = y2 * 64 + 119; x0 = x0 * 64 + 159; x1 = x1 * 64 + 159; x2 = x2 * 64 + 159; float miny, minx; miny = (y0 < y1 && y0 < y2) ? y0 : (y1 < y0 && y1 < y2) ? y1 : y2; minx = (x0 < x1 && x0 < x2) ? x0 : (x1 < x0 && x1 < x2) ? x1 : x2; y0 -= miny; y1 -= miny; y2 -= miny; x0 -= minx; x1 -= minx; x2 -= minx; currentVertex[0] = (y1 - y2) * x0 + (x2 - x1) * y0 + x1*y2 - x2*y1; currentVertex[1] = (y2 - y0) * x1 + (x0 - x2) * y1 + x2*y0 - x0*y2; currentVertex[2] = (y0 - y1) * x2 + (x1 - x0) * y2 + x0*y1 - x1*y0; currentVertex[0] = 1 / currentVertex[0]; currentVertex[1] = 1 / currentVertex[1]; currentVertex[2] = 1 / currentVertex[2]; for (int j = 0; j < 3; j++) { if (Math.abs(currentVertex[j]) >= Math.pow(10,10) || currentVertex[j] == 0) { f.print("000000000000000000"); } else if (currentVertex[j] < 0) { if (currentVertex[j] > -0.5f) { while (currentVertex[j] > -0.5f) { currentVertex[j] *= 2.0f; currentExponent--; } } else { while ( currentVertex[j] <= -1 ) { currentVertex[j] /= 2.0f; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; f.print("1" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } else { if (currentVertex[j] < 0.5f) { while (currentVertex[j] < 0.5f) { currentVertex[j] *= 2.0f; currentExponent--; } } else { //exponent while ( currentVertex[j] >= 1 ) { currentVertex[j] /= 2.0d; currentExponent++; } } currentExponent += 128; exponent = Integer.toBinaryString(currentExponent); exponentLength = exponent.length(); for (int l = 0; l < 8 - exponentLength; l++) exponent = "0" + exponent; int intbits = Float.floatToIntBits(currentVertex[j]); //want bits 22-15, plus tack a 1 on the front intbits = intbits >> 15; intbits = intbits & 0x000000ff; intbits += 256; f.print("0" + exponent + Integer.toBinaryString(intbits)); //System.out.print(" 0" + exponent + Integer.toBinaryString(intbits)); currentExponent = 0; } } f.print("; end "); } f.print("endcase"); //calculate vertex indices and output them vertex[0] = Integer.toBinaryString(faces.elementAt(i).x); vertex[1] = Integer.toBinaryString(faces.elementAt(i).y); vertex[2] = Integer.toBinaryString(faces.elementAt(i).z); for (int j = 0; j < 3; j++) { vertexLength = vertex[j].length(); for (int l = 0; l < 12 - vertexLength; l++) vertex[j] = "0" + vertex[j]; } f.println(" triangle_indices = 36'b" + vertex[0] + vertex[1] + vertex[2] + "; end"); } f.println("\t\tdefault:\t\tbegin constants = 54'b0; triangle_indices = 36'b0; end\n\tendcase\nend\n\nendmodule"); f.close(); ver.close(); reader.close(); } public static float magnitude(ThreeTupleFloat a) { return (float)Math.sqrt(a.x*a.x + a.y*a.y + a.z*a.z); } public static ThreeTupleFloat cross(ThreeTupleFloat a, ThreeTupleFloat b) { return new ThreeTupleFloat(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } }