use of com.mojang.math.Vector4f in project MinecraftForge by MinecraftForge.
the class OBJModel method makeQuad.
private Pair<BakedQuad, Direction> makeQuad(int[][] indices, int tintIndex, Vector4f colorTint, Vector4f ambientColor, TextureAtlasSprite texture, Transformation transform) {
boolean needsNormalRecalculation = false;
for (int[] ints : indices) {
needsNormalRecalculation |= ints.length < 3;
}
Vector3f faceNormal = new Vector3f(0, 0, 0);
if (needsNormalRecalculation) {
Vector3f a = positions.get(indices[0][0]);
Vector3f ab = positions.get(indices[1][0]);
Vector3f ac = positions.get(indices[2][0]);
Vector3f abs = ab.copy();
abs.sub(a);
Vector3f acs = ac.copy();
acs.sub(a);
abs.cross(acs);
abs.normalize();
faceNormal = abs;
}
Vector4f[] pos = new Vector4f[4];
Vector3f[] norm = new Vector3f[4];
BakedQuadBuilder builder = new BakedQuadBuilder(texture);
builder.setQuadTint(tintIndex);
Vec2 uv2 = new Vec2(0, 0);
if (ambientToFullbright) {
int fakeLight = (int) ((ambientColor.x() + ambientColor.y() + ambientColor.z()) * 15 / 3.0f);
uv2 = new Vec2((fakeLight << 4) / 32767.0f, (fakeLight << 4) / 32767.0f);
builder.setApplyDiffuseLighting(fakeLight == 0);
} else {
builder.setApplyDiffuseLighting(diffuseLighting);
}
boolean hasTransform = !transform.isIdentity();
// The incoming transform is referenced on the center of the block, but our coords are referenced on the corner
Transformation transformation = hasTransform ? transform.blockCenterToCorner() : transform;
for (int i = 0; i < 4; i++) {
int[] index = indices[Math.min(i, indices.length - 1)];
Vector3f pos0 = positions.get(index[0]);
Vector4f position = new Vector4f(pos0);
Vec2 texCoord = index.length >= 2 && texCoords.size() > 0 ? texCoords.get(index[1]) : DEFAULT_COORDS[i];
Vector3f norm0 = !needsNormalRecalculation && index.length >= 3 && normals.size() > 0 ? normals.get(index[2]) : faceNormal;
Vector3f normal = norm0;
Vector4f color = index.length >= 4 && colors.size() > 0 ? colors.get(index[3]) : COLOR_WHITE;
if (hasTransform) {
normal = norm0.copy();
transformation.transformPosition(position);
transformation.transformNormal(normal);
}
;
Vector4f tintedColor = new Vector4f(color.x() * colorTint.x(), color.y() * colorTint.y(), color.z() * colorTint.z(), color.w() * colorTint.w());
putVertexData(builder, position, texCoord, normal, tintedColor, uv2, texture);
pos[i] = position;
norm[i] = normal;
}
builder.setQuadOrientation(Direction.getNearest(norm[0].x(), norm[0].y(), norm[0].z()));
Direction cull = null;
if (detectCullableFaces) {
if (// vertex.position.x
Mth.equal(pos[0].x(), 0) && Mth.equal(pos[1].x(), 0) && Mth.equal(pos[2].x(), 0) && Mth.equal(pos[3].x(), 0) && // vertex.normal.x
norm[0].x() < 0) {
cull = Direction.WEST;
} else if (// vertex.position.x
Mth.equal(pos[0].x(), 1) && Mth.equal(pos[1].x(), 1) && Mth.equal(pos[2].x(), 1) && Mth.equal(pos[3].x(), 1) && // vertex.normal.x
norm[0].x() > 0) {
cull = Direction.EAST;
} else if (// vertex.position.z
Mth.equal(pos[0].z(), 0) && Mth.equal(pos[1].z(), 0) && Mth.equal(pos[2].z(), 0) && Mth.equal(pos[3].z(), 0) && // vertex.normal.z
norm[0].z() < 0) {
// can never remember
cull = Direction.NORTH;
} else if (// vertex.position.z
Mth.equal(pos[0].z(), 1) && Mth.equal(pos[1].z(), 1) && Mth.equal(pos[2].z(), 1) && Mth.equal(pos[3].z(), 1) && // vertex.normal.z
norm[0].z() > 0) {
cull = Direction.SOUTH;
} else if (// vertex.position.y
Mth.equal(pos[0].y(), 0) && Mth.equal(pos[1].y(), 0) && Mth.equal(pos[2].y(), 0) && Mth.equal(pos[3].y(), 0) && // vertex.normal.z
norm[0].y() < 0) {
// can never remember
cull = Direction.DOWN;
} else if (// vertex.position.y
Mth.equal(pos[0].y(), 1) && Mth.equal(pos[1].y(), 1) && Mth.equal(pos[2].y(), 1) && Mth.equal(pos[3].y(), 1) && // vertex.normal.y
norm[0].y() > 0) {
cull = Direction.UP;
}
}
return Pair.of(builder.build(), cull);
}
use of com.mojang.math.Vector4f in project MinecraftForge by MinecraftForge.
the class TRSRTransformer method put.
@Override
public void put(int element, float... data) {
switch(getVertexFormat().getElements().get(element).getUsage()) {
case POSITION:
Vector4f pos = new Vector4f(data[0], data[1], data[2], data[3]);
transform.transformPosition(pos);
data[0] = pos.x();
data[1] = pos.y();
data[2] = pos.z();
data[3] = pos.w();
break;
case NORMAL:
Vector3f normal = new Vector3f(data);
transform.transformNormal(normal);
data[0] = normal.x();
data[1] = normal.y();
data[2] = normal.z();
break;
}
super.put(element, data);
}
use of com.mojang.math.Vector4f 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.math.Vector4f in project MinecraftForge by MinecraftForge.
the class IForgeVertexConsumer method putBulkData.
// Copy of putBulkData with alpha support
default void putBulkData(PoseStack.Pose matrixEntry, BakedQuad bakedQuad, float[] baseBrightness, float red, float green, float blue, float alpha, int[] lightmapCoords, int overlayCoords, boolean readExistingColor) {
int[] aint = bakedQuad.getVertices();
Vec3i faceNormal = bakedQuad.getDirection().getNormal();
Vector3f normal = new Vector3f((float) faceNormal.getX(), (float) faceNormal.getY(), (float) faceNormal.getZ());
Matrix4f matrix4f = matrixEntry.pose();
normal.transform(matrixEntry.normal());
int intSize = DefaultVertexFormat.BLOCK.getIntegerSize();
int vertexCount = aint.length / intSize;
try (MemoryStack memorystack = MemoryStack.stackPush()) {
ByteBuffer bytebuffer = memorystack.malloc(DefaultVertexFormat.BLOCK.getVertexSize());
IntBuffer intbuffer = bytebuffer.asIntBuffer();
for (int v = 0; v < vertexCount; ++v) {
((Buffer) intbuffer).clear();
intbuffer.put(aint, v * 8, 8);
float f = bytebuffer.getFloat(0);
float f1 = bytebuffer.getFloat(4);
float f2 = bytebuffer.getFloat(8);
float cr;
float cg;
float cb;
float ca;
if (readExistingColor) {
float r = (float) (bytebuffer.get(12) & 255) / 255.0F;
float g = (float) (bytebuffer.get(13) & 255) / 255.0F;
float b = (float) (bytebuffer.get(14) & 255) / 255.0F;
float a = (float) (bytebuffer.get(15) & 255) / 255.0F;
cr = r * baseBrightness[v] * red;
cg = g * baseBrightness[v] * green;
cb = b * baseBrightness[v] * blue;
ca = a * alpha;
} else {
cr = baseBrightness[v] * red;
cg = baseBrightness[v] * green;
cb = baseBrightness[v] * blue;
ca = alpha;
}
int lightmapCoord = applyBakedLighting(lightmapCoords[v], bytebuffer);
float f9 = bytebuffer.getFloat(16);
float f10 = bytebuffer.getFloat(20);
Vector4f pos = new Vector4f(f, f1, f2, 1.0F);
pos.transform(matrix4f);
applyBakedNormals(normal, bytebuffer, matrixEntry.normal());
((VertexConsumer) this).vertex(pos.x(), pos.y(), pos.z(), cr, cg, cb, ca, f9, f10, overlayCoords, lightmapCoord, normal.x(), normal.y(), normal.z());
}
}
}
use of com.mojang.math.Vector4f in project MinecraftForge by MinecraftForge.
the class QuadTransformer method processVertices.
private void processVertices(int[] inData, int[] outData) {
int stride = DefaultVertexFormat.BLOCK.getVertexSize();
int count = (inData.length * 4) / stride;
for (int i = 0; i < count; i++) {
int offset = POSITION + i * stride;
float x = Float.intBitsToFloat(getAtByteOffset(inData, offset));
float y = Float.intBitsToFloat(getAtByteOffset(inData, offset + 4));
float z = Float.intBitsToFloat(getAtByteOffset(inData, offset + 8));
Vector4f pos = new Vector4f(x, y, z, 1);
transform.transformPosition(pos);
pos.perspectiveDivide();
putAtByteOffset(outData, offset, Float.floatToRawIntBits(pos.x()));
putAtByteOffset(outData, offset + 4, Float.floatToRawIntBits(pos.y()));
putAtByteOffset(outData, offset + 8, Float.floatToRawIntBits(pos.z()));
}
for (int i = 0; i < count; i++) {
int offset = NORMAL + i * stride;
int normalIn = getAtByteOffset(inData, offset);
if (normalIn != 0) {
float x = ((byte) ((normalIn) >> 24)) / 127.0f;
float y = ((byte) ((normalIn << 8) >> 24)) / 127.0f;
float z = ((byte) ((normalIn << 16) >> 24)) / 127.0f;
Vector3f pos = new Vector3f(x, y, z);
transform.transformNormal(pos);
pos.normalize();
int normalOut = ((((byte) (x / 127.0f)) & 0xFF) << 24) | ((((byte) (y / 127.0f)) & 0xFF) << 16) | ((((byte) (z / 127.0f)) & 0xFF) << 8) | (normalIn & 0xFF);
putAtByteOffset(outData, offset, normalOut);
}
}
}
Aggregations