Separated WireModelGenerator class from RenderFlatWire

This commit is contained in:
Calclavia 2014-09-13 18:24:57 +08:00
parent e3c337a4f3
commit f848cc5c78
4 changed files with 399 additions and 473 deletions

View file

@ -919,7 +919,7 @@ public class PartFlatWire extends PartAdvancedWire implements TFacePart, TNormal
@SideOnly(Side.CLIENT)
public IIcon getIcon()
{
return RenderFlatWire.flatWireTexture;
return RenderFlatWire$.MODULE$.flatWireTexture();
}
public Colour getColour()

View file

@ -1,472 +0,0 @@
package resonantinduction.electrical.wire.flat;
import java.util.Arrays;
import java.util.LinkedList;
import codechicken.lib.render.uv.*;
import net.minecraft.util.IIcon;
import codechicken.lib.lighting.LightModel;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.CCModel;
import codechicken.lib.render.ColourMultiplier;
import codechicken.lib.render.RenderUtils;
import codechicken.lib.render.Vertex5;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Transformation;
import codechicken.lib.vec.Translation;
import codechicken.lib.vec.Vector3;
public class RenderFlatWire
{
public static IIcon flatWireTexture;
public static class UVT extends UVTransformation
{
public Transformation t;
private Vector3 vec = new Vector3();
public UVT(Transformation t)
{
this.t = t;
}
@Override
public void apply(UV uv)
{
vec.set(uv.u, 0, uv.v).apply(t);
uv.set(vec.x, vec.z);
}
@Override
public UVTransformation inverse() {
return null;
}
}
public static int[] reorientSide = new int[] { 0, 3, 3, 0, 0, 3 };
/*
* All generations are done on side 0 so know that for rotation r
* 0 = side 3 = +Z = SOUTH
* 1 = side 4 = -X = WEST
* 2 = side 2 = -Z = NORTH
* 3 = side 5 = +X = EAST
*/
private static class WireModelGenerator
{
int side;
int tw;
int th;
double w;
double h;
int mask;
int connMask;
int connCount;
CCModel model;
int i = 0;
boolean inv;
public static int countConnections(int connMask)
{
int n = 0;
for (int r = 0; r < 4; r++)
if ((connMask & 1 << r) != 0)
n += 1;
return n;
}
public int numFaces()
{
if (inv)
return 22;
int conns;
if (connCount <= 2)
conns = 2;
else
conns = connCount;
int faces = conns * 3 + 5;
for (int i = 0; i < 4; i++)
if ((mask >> i & 0x11) == 1)
faces++;
return faces;
}
public CCModel generateInvModel(int thickness)
{
return generateModel(modelKey(0, thickness, 0xF0), true);
}
public CCModel generateModel(int key, boolean inv)
{
this.inv = inv;
side = (key >> 8) % 6;
tw = (key >> 8) / 6 + 1;
w = tw / 16D;
th = tw + 1;
h = th / 16D;
mask = key & 0xFF;
connMask = (mask & 0xF0) >> 4 | mask & 0xF;
connCount = countConnections(connMask);
model = CCModel.quadModel(numFaces() * 4);
i = 0;
generateCenter();
for (int r = 0; r < 4; r++)
generateSide(r);
model.apply(Rotation.sideOrientation(side, 0).at(Vector3.center));
return finishModel(model);
}
private void generateSide(int r)
{
int type = mask >> r & 0x11;
Vertex5[] verts;
if (inv)
verts = generateSideInv(r);
else if (connCount == 0)
if (r % 2 == 1)
verts = generateStub(r);
else
verts = generateFlat(r);
else if (connCount == 1)
if (connMask == 1 << (r + 2) % 4)// this side is opposite the one with a connection
verts = generateStub(r);
else
verts = generateSideFromType(type, r);
else
verts = generateSideFromType(type, r);
Transformation t = Rotation.quarterRotations[r].at(Vector3.center);
for (Vertex5 vert : verts)
vert.apply(t);
i = addVerts(model, verts, i);
}
private Vertex5[] generateSideInv(int r)
{
return withBottom(generateStraight(r), 4, 4);
}
private Vertex5[] generateSideFromType(int type, int r)
{
if (type == 0x00)
return generateFlat(r);
else if (type == 0x01)
return generateCorner(r);
else if (type == 0x10)
return generateStraight(r);
else
return generateInternal(r);
}
private Vertex5[] generateFlat(int r)
{
Vertex5[] verts = new Vertex5[] { new Vertex5(0.5 - w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 - tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 - tw), new Vertex5(0.5 - w, h, 0.5 + w, 16 - th, 16 + tw) };
if (Rotation.rotateSide(side, r) % 2 == 0) // red is on the negative side
{
UVT uvt = new UVT(Rotation.quarterRotations[2].at(new Vector3(8, 0, 16)));
for (Vertex5 vert : verts)
vert.apply(uvt);
}
return verts;
}
private Vertex5[] generateStub(int r)
{
Vertex5[] verts = generateExtension(4);
for (int i = 0; i < 4; i++)
verts[i].vec.z -= 0.002;// pull the stub in a little so it
// doesn't z fight with jacketed cables
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateStraight(int r)
{
Vertex5[] verts = generateExtension(8);
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateCorner(int r)
{
Vertex5[] verts = generateExtension(8 + th);
// retexture cap
for (int i = 0; i < 4; i++)
verts[i].apply(new UVTranslation(0, -th));
// add end face extending around block
verts = Arrays.copyOf(verts, 20);
verts[16] = new Vertex5(0.5 - w, 0, 1, 8 - tw, 24 + 2 * th);
verts[17] = new Vertex5(0.5 + w, 0, 1, 8 + tw, 24 + 2 * th);
verts[18] = new Vertex5(0.5 + w, 0, 1 + h, 8 + tw, 24 + th);
verts[19] = new Vertex5(0.5 - w, 0, 1 + h, 8 - tw, 24 + th);
reflectSide(verts, r);
return verts;
}
private Vertex5[] generateInternal(int r)
{
Vertex5[] verts = generateExtension(8);
// retexture cap
verts[0].uv.set(8 + tw, 24);
verts[1].uv.set(8 - tw, 24);
verts[2].uv.set(8 - tw, 24 + tw);
verts[3].uv.set(8 + tw, 24 + tw);
reflectSide(verts, r);
// offset side textures
for (int i = 4; i < 16; i++)
verts[i].apply(new UVTranslation(16, 0));
return verts;
}
private Vertex5[] generateExtension(int tl)
{
double l = tl / 16D;
return new Vertex5[] {// cap
new Vertex5(0.5 - w, 0, 0.5 + l, 8 - tw, 24 + 2 * th), new Vertex5(0.5 + w, 0, 0.5 + l, 8 + tw, 24 + 2 * th), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 24 + th), new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 24 + th),
// top
new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw),
// left
new Vertex5(0.5 - w, 0, 0.5 + w, 0, 16 + tw), new Vertex5(0.5 - w, 0, 0.5 + l, 0, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + l, th, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + w, th, 16 + tw),
// right
new Vertex5(0.5 + w, 0, 0.5 + l, 16, 16 + tl), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + l, 16 - th, 16 + tl) };
}
private void generateCenter()
{
int tex;// 0 = straight n/s, 1 = straight e/w, 2 = circle
if (connCount == 0)
tex = 1;
else if (connCount == 1)
tex = (connMask & 5) != 0 ? 0 : 1;// if there is one connection, and it is
// north/south then north/south, otherwise
// east/west
else if (connMask == 5)
tex = 0;
else if (connMask == 10)
tex = 1;
else
tex = 2;
Vertex5[] verts = new Vertex5[] { new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 - w, 8 + tw, 16 - tw), new Vertex5(0.5 - w, h, 0.5 - w, 8 - tw, 16 - tw) };
if (tex == 0 || tex == 1)
tex = (tex + reorientSide[side]) % 2;
int r = reorientSide[side];
if (tex == 1)
r += 3;
if (r != 0)
{
UVTransformation uvt = new UVT(Rotation.quarterRotations[r % 4].at(new Vector3(8, 0, 16)));
for (Vertex5 vert : verts)
vert.apply(uvt);
}
if (tex == 2)
{// circle (translate across to u = 24)
UVTranslation uvt = new UVTranslation(16, 0);
for (Vertex5 vert : verts)
vert.apply(uvt);
}
if (inv)
verts = withBottom(verts, 0, 4);
i = addVerts(model, verts, i);
}
private static UVT sideReflect = new UVT(Rotation.quarterRotations[2].at(new Vector3(8, 0, 16)));
private void reflectSide(Vertex5[] verts, int r)
{
if ((r + reorientSide[side]) % 4 >= 2)// rotate the texture about
// the y center
for (Vertex5 vert : verts)
vert.apply(sideReflect);
}
/**
* Returns a copy of vertices with the bottom face added at the start.
*
* @param start The index of the first vertex making up the top face
* @param count The number of vertices making up the top face
*/
private Vertex5[] withBottom(Vertex5[] verts, int start, int count)
{
Vertex5[] i_verts = new Vertex5[verts.length + count];
// add the bottom face, just a copy of the top, rotated about the z
// axis
Transformation r = new Rotation(MathHelper.pi, 0, 0, 1).at(new Vector3(0.5, h / 2, 0));
for (int i = 0; i < count; i++)
i_verts[i] = verts[i + start].copy().apply(r);
System.arraycopy(verts, 0, i_verts, count, verts.length);
return i_verts;
}
}
/**
* Array of all built models. These will be generated on demand.
*/
public static CCModel[] wireModels = new CCModel[3 * 6 * 256];
public static CCModel[] invModels = new CCModel[3];
private static WireModelGenerator gen_inst = new WireModelGenerator();
/**
* Puts verts into model m starting at index k
*/
public static int addVerts(CCModel m, Vertex5[] verts, int k)
{
for (int i = 0; i < verts.length; i++)
m.verts[k + i] = verts[i];
return k + verts.length;
}
public static CCModel finishModel(CCModel m)
{
m.apply(new UVScale(1 / 32D));
m.shrinkUVs(0.0005);
m.computeNormals();
m.computeLighting(LightModel.standardLightModel);
return m;
}
/**
* Returns a tightly packed unique index for the specific model represented
* by this wire. The mask is split into 3 sections the combination of
* corresponding bits from the two lowest nybbles gives the connection type
* in that direction.
* 00 = none
* 01 = corner
* 10 = straight
* 11 = internal The
* second byte contains the thickness*6+side
*
* @param side The side the wire is attached to
* @param thickness The thickness of the wire -1 in 1/8th blocks. Supported
* values 0, 1, 2
* @param connMap The connection mask of the wire
*/
public static int modelKey(int side, int thickness, int connMap)
{
int key = connMap & 0xFF;// take the straight and corner connections
int renderCorner = connMap >> 20 & 0xF;
key |= (renderCorner ^ key & 0xF) << 4;// any corner connections that aren't rendered
// convert to straight
key &= ~0xF | renderCorner;// set corners to renderCorners
int internal = (connMap & 0xF00) >> 8;// internal connections
key |= internal << 4 | internal;// if internal is set, set both straight and corner to 1
key |= side + thickness * 6 << 8;// add side and thickness
return key;
}
public static int modelKey(PartFlatWire w)
{
return modelKey(w.side, w.getThickness(), w.connMap);
}
public static CCModel getOrGenerateModel(int key)
{
CCModel m = wireModels[key];
if (m == null)
wireModels[key] = m = gen_inst.generateModel(key, false);
return m;
}
public static void render(PartFlatWire w, Vector3 pos)
{
//TODO
//IVertexModifier m = w.getColour().pack() == -1 ? ColourModifier.instance : new ColourMultiplier(w.getColour());
//CCModel model = getOrGenerateModel(modelKey(w));
//model.render(new Translation(pos), new IconTransformation(w.getIcon()), m);
}
public static void renderInv(int thickness, Transformation t, IIcon icon)
{
CCModel m = invModels[thickness];
if (m == null)
invModels[thickness] = m = gen_inst.generateInvModel(thickness);
m.render(t, new IconTransformation(icon));
}
public static void renderBreakingOverlay(IIcon icon, PartFlatWire wire)
{
int key = modelKey(wire);
int side = (key >> 8) % 6;
double w = ((key >> 8) / 6 + 1) / 16D;
double h = w + 1 / 16D;
int mask = key & 0xFF;
int connMask = (mask & 0xF0) >> 4 | mask & 0xF;
int connCount = WireModelGenerator.countConnections(connMask);
LinkedList<Cuboid6> boxes = new LinkedList<Cuboid6>();
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 - w, 0.5 + w, h, 0.5 + w).apply(Rotation.sideRotations[side].at(Vector3.center)));// center
for (int r = 0; r < 4; r++)
{
int length;
if (connCount == 0)
{
if (r % 2 == 1)
length = 4;
else
length = 0;
}
else if (connCount == 1)
{
if (connMask == 1 << (r + 2) % 4)// this side is opposite the one with a connection
length = 4;
else if (connMask == 1 << r)
length = 8;
else
length = 0;
}
else
length = (connMask & 1 << r) != 0 ? 8 : 0;
if (length > 0)
{
double l = length / 16D;
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 + w, 0.5 + w, h, 0.5 + l).apply(Rotation.sideOrientation(side, r).at(Vector3.center)));
}
}
//TODO for (Cuboid6 box : boxes)
//RenderUtils.renderBlock(box, 0, new Translation(wire.x(), wire.y(), wire.z()), new IconTransformation(icon), null);
}
}

View file

@ -0,0 +1,156 @@
package resonantinduction.electrical.wire.flat
import java.util.{Arrays, LinkedList}
import codechicken.lib.lighting.LightModel
import codechicken.lib.math.MathHelper
import codechicken.lib.render._
import codechicken.lib.render.uv._
import codechicken.lib.vec.{Cuboid6, Rotation, Transformation, Translation, Vector3}
import net.minecraft.util.IIcon
object RenderFlatWire
{
/**
* Puts verts into model m starting at index k
*/
def addVerts(m: CCModel, verts: Array[Vertex5], k: Int): Int =
{
{
var i: Int = 0
while (i < verts.length)
{
m.verts(k + i) = verts(i)
({i += 1; i - 1 })
}
}
return k + verts.length
}
def finishModel(m: CCModel): CCModel =
{
m.apply(new UVScale(1 / 32D))
m.shrinkUVs(0.0005)
m.computeNormals
m.computeLighting(LightModel.standardLightModel)
return m
}
/**
* Returns a tightly packed unique index for the specific model represented
* by this wire. The mask is split into 3 sections the combination of
* corresponding bits from the two lowest nybbles gives the connection type
* in that direction.
* 00 = none
* 01 = corner
* 10 = straight
* 11 = internal The
* second byte contains the thickness*6+side
*
* @param side The side the wire is attached to
* @param thickness The thickness of the wire -1 in 1/8th blocks. Supported
* values 0, 1, 2
* @param connMap The connection mask of the wire
*/
def modelKey(side: Int, thickness: Int, connMap: Int): Int =
{
var key: Int = connMap & 0xFF
val renderCorner: Int = connMap >> 20 & 0xF
key |= (renderCorner ^ key & 0xF) << 4
key &= ~0xF | renderCorner
val internal: Int = (connMap & 0xF00) >> 8
key |= internal << 4 | internal
key |= side + thickness * 6 << 8
return key
}
def modelKey(w: PartFlatWire): Int =
{
return modelKey(w.side, w.getThickness, w.connMap)
}
def getOrGenerateModel(key: Int): CCModel =
{
var m: CCModel = wireModels(key)
if (m == null) wireModels(key) =
{m = gen_inst.generateModel(key, false); m }
return m
}
def render(wire: PartFlatWire, pos: Vector3)
{
val colorCode = wire.getColour.pack
val operation = if (colorCode == -1) ColourMultiplier.instance(0xFFFFFF) else new ColourMultiplier(colorCode)
val model: CCModel = getOrGenerateModel(modelKey(wire))
model.render(new Translation(pos), new IconTransformation(wire.getIcon), operation)
}
def renderInv(thickness: Int, t: Transformation, icon: IIcon)
{
var m: CCModel = invModels(thickness)
if (m == null) invModels(thickness) =
{m = gen_inst.generateInvModel(thickness); m }
m.render(t, new IconTransformation(icon))
}
def renderBreakingOverlay(icon: IIcon, wire: PartFlatWire)
{
val key: Int = modelKey(wire)
val side: Int = (key >> 8) % 6
val w: Double = ((key >> 8) / 6 + 1) / 16D
val h: Double = w + 1 / 16D
val mask: Int = key & 0xFF
val connMask: Int = (mask & 0xF0) >> 4 | mask & 0xF
val connCount: Int = WireModelGenerator.countConnections(connMask)
val boxes: LinkedList[Cuboid6] = new LinkedList[Cuboid6]
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 - w, 0.5 + w, h, 0.5 + w).apply(Rotation.sideRotations(side).at(Vector3.center)))
for (r <- (0 until 4))
{
var length: Int = 0
if (connCount == 0)
{
if (r % 2 == 1) length = 4
else length = 0
}
else if (connCount == 1)
{
if (connMask == (1 << (r + 2) % 4)) length = 4
else if (connMask == (1 << r)) length = 8
else length = 0
}
else length = if ((connMask & 1 << r) != 0) 8 else 0
if (length > 0)
{
val l: Double = length / 16D
boxes.add(new Cuboid6(0.5 - w, 0, 0.5 + w, 0.5 + w, h, 0.5 + l).apply(Rotation.sideOrientation(side, r).at(Vector3.center)))
}
}
}
var flatWireTexture: IIcon = null
var reorientSide: Array[Int] = Array[Int](0, 3, 3, 0, 0, 3)
/**
* Array of all built models. These will be generated on demand.
*/
var wireModels: Array[CCModel] = new Array[CCModel](3 * 6 * 256)
var invModels: Array[CCModel] = new Array[CCModel](3)
val gen_inst = new WireModelGenerator
class UVT(t: Transformation) extends UVTransformation
{
val vec = new Vector3
def apply(uv: UV)
{
vec.set(uv.u, 0, uv.v).apply(t)
uv.set(vec.x, vec.z)
}
def inverse: UVTransformation =
{
return null
}
}
}

View file

@ -0,0 +1,242 @@
package resonantinduction.electrical.wire.flat
import java.util.Arrays
import codechicken.lib.math.MathHelper
import codechicken.lib.render.uv.{UVTransformation, UVTranslation}
import codechicken.lib.render.{Vertex5, CCModel}
import codechicken.lib.vec.{Transformation, Vector3, Rotation}
/**
* @author Calclavia
*/
object WireModelGenerator
{
val sideReflect = new RenderFlatWire.UVT(Rotation.quarterRotations(2).at(new Vector3(8, 0, 16)))
def countConnections(connMask: Int): Int =
{
var n: Int = 0
for (r <- 0 until 4)
{
if ((connMask & 1 << r) != 0) n += 1
}
return n
}
}
class WireModelGenerator
{
private[flat] var side: Int = 0
private[flat] var tw: Int = 0
private[flat] var th: Int = 0
private[flat] var w: Double = .0
private[flat] var h: Double = .0
private[flat] var mask: Int = 0
private[flat] var connMask: Int = 0
private[flat] var connCount: Int = 0
private[flat] var model: CCModel = null
private[flat] var i: Int = 0
private[flat] var inv: Boolean = false
def numFaces: Int =
{
if (inv) return 22
var conns: Int = 0
if (connCount <= 2) conns = 2
else conns = connCount
var faces: Int = conns * 3 + 5
for (i <- 0 until 4)
{
if ((mask >> i & 0x11) == 1)
faces += 1
}
return faces
}
def generateInvModel(thickness: Int): CCModel =
{
return generateModel(RenderFlatWire.modelKey(0, thickness, 0xF0), true)
}
def generateModel(key: Int, inv: Boolean): CCModel =
{
this.inv = inv
side = (key >> 8) % 6
tw = (key >> 8) / 6 + 1
w = tw / 16D
th = tw + 1
h = th / 16D
mask = key & 0xFF
connMask = (mask & 0xF0) >> 4 | mask & 0xF
connCount = WireModelGenerator.countConnections(connMask)
model = CCModel.quadModel(numFaces * 4)
i = 0
generateCenter
var r: Int = 0
while (r < 4)
{
generateSide(r)
({r += 1; r - 1 })
}
model.apply(Rotation.sideOrientation(side, 0).at(Vector3.center))
return RenderFlatWire.finishModel(model)
}
private def generateSide(r: Int)
{
val `type`: Int = mask >> r & 0x11
var verts: Array[Vertex5] = null
if (inv) verts = generateSideInv(r)
else if (connCount == 0) if (r % 2 == 1) verts = generateStub(r)
else verts = generateFlat(r)
else if (connCount == 1) if (connMask == (1 << (r + 2) % 4)) verts = generateStub(r)
else verts = generateSideFromType(`type`, r)
else verts = generateSideFromType(`type`, r)
val t: Transformation = Rotation.quarterRotations(r).at(Vector3.center)
for (vert <- verts) vert.apply(t)
i = RenderFlatWire.addVerts(model, verts, i)
}
private def generateSideInv(r: Int): Array[Vertex5] =
{
return withBottom(generateStraight(r), 4, 4)
}
private def generateSideFromType(`type`: Int, r: Int): Array[Vertex5] =
{
if (`type` == 0x00) return generateFlat(r)
else if (`type` == 0x01) return generateCorner(r)
else if (`type` == 0x10) return generateStraight(r)
else return generateInternal(r)
}
private def generateFlat(r: Int): Array[Vertex5] =
{
val verts: Array[Vertex5] = Array[Vertex5](new Vertex5(0.5 - w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 - tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 - tw), new Vertex5(0.5 - w, h, 0.5 + w, 16 - th, 16 + tw))
if (Rotation.rotateSide(side, r) % 2 == 0)
{
val uvt: RenderFlatWire.UVT = new RenderFlatWire.UVT(Rotation.quarterRotations(2).at(new Vector3(8, 0, 16)))
for (vert <- verts) vert.apply(uvt)
}
return verts
}
private def generateStub(r: Int): Array[Vertex5] =
{
val verts: Array[Vertex5] = generateExtension(4)
for (i <- 0 until 4)
{
verts(i).vec.z -= 0.002
}
reflectSide(verts, r)
return verts
}
private def generateStraight(r: Int): Array[Vertex5] =
{
val verts: Array[Vertex5] = generateExtension(8)
reflectSide(verts, r)
return verts
}
private def generateCorner(r: Int): Array[Vertex5] =
{
var verts = generateExtension(8 + th)
for (i <- 0 until 4)
{
verts(i).apply(new UVTranslation(0, -th))
}
verts = Arrays.copyOf(verts, 20)
verts(16) = new Vertex5(0.5 - w, 0, 1, 8 - tw, 24 + 2 * th)
verts(17) = new Vertex5(0.5 + w, 0, 1, 8 + tw, 24 + 2 * th)
verts(18) = new Vertex5(0.5 + w, 0, 1 + h, 8 + tw, 24 + th)
verts(19) = new Vertex5(0.5 - w, 0, 1 + h, 8 - tw, 24 + th)
reflectSide(verts, r)
return verts
}
private def generateInternal(r: Int): Array[Vertex5] =
{
val verts: Array[Vertex5] = generateExtension(8)
verts(0).uv.set(8 + tw, 24)
verts(1).uv.set(8 - tw, 24)
verts(2).uv.set(8 - tw, 24 + tw)
verts(3).uv.set(8 + tw, 24 + tw)
reflectSide(verts, r)
for (i <- 4 until 16)
{
verts(i).apply(new UVTranslation(16, 0))
}
return verts
}
private def generateExtension(tl: Int): Array[Vertex5] =
{
val l: Double = tl / 16D
return Array[Vertex5](new Vertex5(0.5 - w, 0, 0.5 + l, 8 - tw, 24 + 2 * th), new Vertex5(0.5 + w, 0, 0.5 + l, 8 + tw, 24 + 2 * th), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 24 + th), new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 24 + th), new Vertex5(0.5 - w, h, 0.5 + l, 8 - tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + l, 8 + tw, 16 + tl), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw), new Vertex5(0.5 - w, 0, 0.5 + w, 0, 16 + tw), new Vertex5(0.5 - w, 0, 0.5 + l, 0, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + l, th, 16 + tl), new Vertex5(0.5 - w, h, 0.5 + w, th, 16 + tw), new Vertex5(0.5 + w, 0, 0.5 + l, 16, 16 + tl), new Vertex5(0.5 + w, 0, 0.5 + w, 16, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 16 - th, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + l, 16 - th, 16 + tl))
}
private def generateCenter
{
var tex: Int = 0
if (connCount == 0) tex = 1
else if (connCount == 1) tex = if ((connMask & 5) != 0) 0 else 1
else if (connMask == 5) tex = 0
else if (connMask == 10) tex = 1
else tex = 2
var verts: Array[Vertex5] = Array[Vertex5](new Vertex5(0.5 - w, h, 0.5 + w, 8 - tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 + w, 8 + tw, 16 + tw), new Vertex5(0.5 + w, h, 0.5 - w, 8 + tw, 16 - tw), new Vertex5(0.5 - w, h, 0.5 - w, 8 - tw, 16 - tw))
if (tex == 0 || tex == 1) tex = (tex + RenderFlatWire.reorientSide(side)) % 2
var r: Int = RenderFlatWire.reorientSide(side)
if (tex == 1) r += 3
if (r != 0)
{
val uvt: UVTransformation = new RenderFlatWire.UVT(Rotation.quarterRotations(r % 4).at(new Vector3(8, 0, 16)))
for (vert <- verts) vert.apply(uvt)
}
if (tex == 2)
{
val uvt: UVTranslation = new UVTranslation(16, 0)
for (vert <- verts) vert.apply(uvt)
}
if (inv) verts = withBottom(verts, 0, 4)
i = RenderFlatWire.addVerts(model, verts, i)
}
private def reflectSide(verts: Array[Vertex5], r: Int)
{
if ((r + RenderFlatWire.reorientSide(side)) % 4 >= 2) for (vert <- verts) vert.apply(WireModelGenerator.sideReflect)
}
/**
* Returns a copy of vertices with the bottom face added at the start.
*
* @param start The index of the first vertex making up the top face
* @param count The number of vertices making up the top face
*/
private def withBottom(verts: Array[Vertex5], start: Int, count: Int): Array[Vertex5] =
{
val i_verts: Array[Vertex5] = new Array[Vertex5](verts.length + count)
val r: Transformation = new Rotation(MathHelper.pi, 0, 0, 1).at(new Vector3(0.5, h / 2, 0))
for (i <- 0 until count)
{
i_verts(i) = verts(i + start).copy.apply(r)
}
System.arraycopy(verts, 0, i_verts, count, verts.length)
return i_verts
}
}