use of com.mojang.blaze3d.vertex.VertexFormatElement in project MinecraftForge by MinecraftForge.
the class LightUtil method pack.
public static void pack(float[] from, int[] to, VertexFormat formatTo, int v, int e) {
VertexFormatElement element = formatTo.getElements().get(e);
int vertexStart = v * formatTo.getVertexSize() + formatTo.getOffset(e);
int count = element.getElementCount();
VertexFormatElement.Type type = element.getType();
int size = type.getSize();
int mask = (256 << (8 * (size - 1))) - 1;
for (int i = 0; i < 4; i++) {
if (i < count) {
int pos = vertexStart + size * i;
int index = pos >> 2;
int offset = pos & 3;
int bits = 0;
float f = i < from.length ? from[i] : 0;
if (type == VertexFormatElement.Type.FLOAT) {
bits = Float.floatToRawIntBits(f);
} else if (type == VertexFormatElement.Type.UBYTE || type == VertexFormatElement.Type.USHORT || type == VertexFormatElement.Type.UINT) {
bits = Math.round(f * mask);
} else {
bits = Math.round(f * (mask >> 1));
}
to[index] &= ~(mask << (offset * 8));
to[index] |= (((bits & mask) << (offset * 8)));
// TODO handle overflow into to[index + 1]
}
}
}
use of com.mojang.blaze3d.vertex.VertexFormatElement in project MinecraftForge by MinecraftForge.
the class LightUtil method unpack.
public static void unpack(int[] from, float[] to, VertexFormat formatFrom, int v, int e) {
int length = 4 < to.length ? 4 : to.length;
VertexFormatElement element = formatFrom.getElements().get(e);
int vertexStart = v * formatFrom.getVertexSize() + formatFrom.getOffset(e);
int count = element.getElementCount();
VertexFormatElement.Type type = element.getType();
VertexFormatElement.Usage usage = element.getUsage();
int size = type.getSize();
int mask = (256 << (8 * (size - 1))) - 1;
for (int i = 0; i < length; i++) {
if (i < count) {
int pos = vertexStart + size * i;
int index = pos >> 2;
int offset = pos & 3;
int bits = from[index];
bits = bits >>> (offset * 8);
if ((pos + size - 1) / 4 != index) {
bits |= from[index + 1] << ((4 - offset) * 8);
}
bits &= mask;
if (type == VertexFormatElement.Type.FLOAT) {
to[i] = Float.intBitsToFloat(bits);
} else if (type == VertexFormatElement.Type.UBYTE || type == VertexFormatElement.Type.USHORT) {
to[i] = (float) bits / mask;
} else if (type == VertexFormatElement.Type.UINT) {
to[i] = (float) ((double) (bits & 0xFFFFFFFFL) / 0xFFFFFFFFL);
} else if (type == VertexFormatElement.Type.BYTE) {
to[i] = ((float) (byte) bits) / (mask >> 1);
} else if (type == VertexFormatElement.Type.SHORT) {
to[i] = ((float) (short) bits) / (mask >> 1);
} else if (type == VertexFormatElement.Type.INT) {
to[i] = (float) ((double) (bits & 0xFFFFFFFFL) / (0xFFFFFFFFL >> 1));
}
} else {
to[i] = (i == 3 && usage == VertexFormatElement.Usage.POSITION) ? 1 : 0;
}
}
}
use of com.mojang.blaze3d.vertex.VertexFormatElement in project MinecraftForge by MinecraftForge.
the class BakedQuadBuilder method build.
public BakedQuad build() {
if (!full) {
throw new IllegalStateException("not enough data");
}
if (texture == null) {
throw new IllegalStateException("texture not set");
}
if (contractUVs) {
float tX = texture.getWidth() / (texture.getU1() - texture.getU0());
float tY = texture.getHeight() / (texture.getV1() - texture.getV0());
float tS = tX > tY ? tX : tY;
float ep = 1f / (tS * 0x100);
int uve = 0;
ImmutableList<VertexFormatElement> elements = DefaultVertexFormat.BLOCK.getElements();
while (uve < elements.size()) {
VertexFormatElement e = elements.get(uve);
if (e.getUsage() == VertexFormatElement.Usage.UV && e.getIndex() == 0) {
break;
}
uve++;
}
if (uve == elements.size()) {
throw new IllegalStateException("Can't contract UVs: format doesn't contain UVs");
}
float[] uvc = new float[4];
for (int v = 0; v < 4; v++) {
for (int i = 0; i < 4; i++) {
uvc[i] += unpackedData[v][uve][i] / 4;
}
}
for (int v = 0; v < 4; v++) {
for (int i = 0; i < 4; i++) {
float uo = unpackedData[v][uve][i];
float un = uo * (1 - eps) + uvc[i] * eps;
float ud = uo - un;
float aud = ud;
if (aud < 0)
aud = -aud;
if (// not moving a fraction of a pixel
aud < ep) {
float udc = uo - uvc[i];
if (udc < 0)
udc = -udc;
if (// center is closer than 2 fractions of a pixel, don't move too close
udc < 2 * ep) {
un = (uo + uvc[i]) / 2;
} else // move at least by a fraction
{
un = uo + (ud < 0 ? ep : -ep);
}
}
unpackedData[v][uve][i] = un;
}
}
}
int[] packed = new int[DefaultVertexFormat.BLOCK.getIntegerSize() * 4];
for (int v = 0; v < 4; v++) {
for (int e = 0; e < SIZE; e++) {
LightUtil.pack(unpackedData[v][e], packed, DefaultVertexFormat.BLOCK, v, e);
}
}
return new BakedQuad(packed, tint, orientation, texture, applyDiffuseLighting);
}
use of com.mojang.blaze3d.vertex.VertexFormatElement in project MinecraftForge by MinecraftForge.
the class VertexLighterFlat method processQuad.
@Override
protected void processQuad() {
float[][] position = quadData[posIndex];
float[][] normal = null;
float[][] lightmap = quadData[lightmapIndex];
float[][] color = quadData[colorIndex];
if (dataLength[normalIndex] >= 3 && (quadData[normalIndex][0][0] != 0 || quadData[normalIndex][0][1] != 0 || quadData[normalIndex][0][2] != 0)) {
normal = quadData[normalIndex];
} else // normals must be generated
{
normal = new float[4][4];
Vector3f v1 = new Vector3f(position[3]);
Vector3f t = new Vector3f(position[1]);
Vector3f v2 = new Vector3f(position[2]);
v1.sub(t);
t.set(position[0]);
v2.sub(t);
v2.cross(v1);
v2.normalize();
for (int v = 0; v < 4; v++) {
normal[v][0] = v2.x();
normal[v][1] = v2.y();
normal[v][2] = v2.z();
normal[v][3] = 0;
}
}
int multiplier = -1;
if (tint != -1) {
multiplier = blockInfo.getColorMultiplier(tint);
}
VertexFormat format = parent.getVertexFormat();
int count = format.getElements().size();
for (int v = 0; v < 4; v++) {
float x = position[v][0] - .5f;
float y = position[v][1] - .5f;
float z = position[v][2] - .5f;
// if(blockInfo.getState().getBlock().isFullCube(blockInfo.getState()))
{
x += normal[v][0] * .5f;
y += normal[v][1] * .5f;
z += normal[v][2] * .5f;
}
float blockLight = lightmap[v][0] * LIGHTMAP_RESCALE, skyLight = lightmap[v][1] * LIGHTMAP_RESCALE;
updateLightmap(normal[v], lightmap[v], x, y, z);
if (dataLength[lightmapIndex] > 1) {
if (blockLight > lightmap[v][0])
lightmap[v][0] = blockLight;
if (skyLight > lightmap[v][1])
lightmap[v][1] = skyLight;
}
updateColor(normal[v], color[v], x, y, z, tint, multiplier);
if (diffuse) {
float d = LightUtil.diffuseLight(normal[v][0], normal[v][1], normal[v][2]);
for (int i = 0; i < 3; i++) {
color[v][i] *= d;
}
}
// no need for remapping cause all we could've done is add 1 element to the end
for (int e = 0; e < count; e++) {
VertexFormatElement element = format.getElements().get(e);
switch(element.getUsage()) {
case POSITION:
final Vector4f pos = new Vector4f(position[v][0], position[v][1], position[v][2], 1);
pos.transform(pose.pose());
position[v][0] = pos.x();
position[v][1] = pos.y();
position[v][2] = pos.z();
parent.put(e, position[v]);
break;
case NORMAL:
final Vector3f norm = new Vector3f(normal[v]);
norm.transform(pose.normal());
normal[v][0] = norm.x();
normal[v][1] = norm.y();
normal[v][2] = norm.z();
parent.put(e, normal[v]);
break;
case COLOR:
parent.put(e, color[v]);
break;
case UV:
if (element.getIndex() == 2) {
parent.put(e, lightmap[v]);
break;
}
// else fallthrough to default
default:
parent.put(e, quadData[e][v]);
}
}
}
tint = -1;
}
use of com.mojang.blaze3d.vertex.VertexFormatElement in project MinecraftForge by MinecraftForge.
the class QuadTransformer method findPositionOffset.
private static int findPositionOffset(VertexFormat fmt) {
int index;
VertexFormatElement element = null;
for (index = 0; index < fmt.getElements().size(); index++) {
VertexFormatElement el = fmt.getElements().get(index);
if (el.getUsage() == VertexFormatElement.Usage.POSITION) {
element = el;
break;
}
}
if (index == fmt.getElements().size() || element == null)
throw new RuntimeException("Expected vertex format to have a POSITION attribute");
if (element.getType() != VertexFormatElement.Type.FLOAT)
throw new RuntimeException("Expected POSITION attribute to have data type FLOAT");
if (element.getByteSize() < 3)
throw new RuntimeException("Expected POSITION attribute to have at least 3 dimensions");
return fmt.getOffset(index);
}
Aggregations