Skip to content

Commit

Permalink
Fixed multiple instances
Browse files Browse the repository at this point in the history
  • Loading branch information
Ocelot5836 committed Jan 18, 2025
1 parent 52562a1 commit 8f5f872
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 81 deletions.
3 changes: 1 addition & 2 deletions buildSrc/src/main/groovy/multiloader-common.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ base {
java {
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
withSourcesJar()
withJavadocJar()
}

if (System.getenv('BUILD_NUMBER') != null) {
Expand Down Expand Up @@ -61,7 +60,7 @@ repositories {

// Declare capabilities on the outgoing configurations.
// Read more about capabilities here: https://docs.gradle.org/current/userguide/component_capabilities.html#sec:declaring-additional-capabilities-for-a-local-component
['apiElements', 'runtimeElements', 'sourcesElements', 'javadocElements'].each { variant ->
['apiElements', 'runtimeElements', 'sourcesElements'].each { variant ->
configurations."$variant".outgoing {
capability("$group:${base.archivesName.get()}:$version")
capability("$group:$mod_id-${project.name}-${minecraft_version}:$version")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public abstract class Skeleton {

public static final int MAX_BONES = 256;
public static final int UNIFORM_STRIDE = 32 * Float.BYTES;
public static final int UNIFORM_STRIDE = 28 * Float.BYTES;

public List<Bone> roots;
public Map<String, Bone> bones;
Expand Down Expand Up @@ -87,7 +87,7 @@ public void storeInstancedData(ByteBuffer buffer, Collection<Bone> bones, Object
bone.getColor(color, partialTicks);
color.get(id * UNIFORM_STRIDE + 12 * Float.BYTES, buffer);
// Workaround for a JOML bug with get3x4
new Matrix4f().set(matrix.normal(normalMatrix)).get(id * UNIFORM_STRIDE + 16 * Float.BYTES, buffer);
matrix.normal(normalMatrix).get3x4(id * UNIFORM_STRIDE + 16 * Float.BYTES, buffer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.lwjgl.opengl.GL11C.GL_TRIANGLES;
Expand All @@ -42,46 +41,43 @@ public class Skin implements NativeResource {

private final VertexArray vertexArray;
private final Object2IntMap<String> boneIds;
private final int uniformSize;
private final Vector4f color;

private int instancedBuffer;
private int instances;

private final Matrix3f normalMatrix;
private Matrix4x3f[] matrixStack;
private Quaternionf[] orientationStack;

public Skin(VertexArray vertexArray, Object2IntMap<String> boneIds, int uniformSize) {
public Skin(VertexArray vertexArray, Object2IntMap<String> boneIds) {
this.vertexArray = vertexArray;
this.boneIds = boneIds;
this.uniformSize = uniformSize;
this.color = new Vector4f();

this.normalMatrix = new Matrix3f();
this.matrixStack = null;
this.orientationStack = null;
}

public int getSkeletonDataSize() {
return Skeleton.UNIFORM_STRIDE * this.boneIds.size();
}

@ApiStatus.Internal
public void render(RenderType renderType, List<Matrix4f> transforms, Collection<Skeleton> skeletons, int instancedBuffer, int boneBuffer, DynamicShaderBlock<?> boneBlock, FloatList partialTicks) {
public void render(RenderType renderType, List<Matrix4f> transforms, List<Skeleton> skeletons, int instancedBuffer, int boneBuffer, DynamicShaderBlock<?> boneBlock, FloatList partialTicks) {
if (skeletons.isEmpty()) {
return;
}

if (this.instancedBuffer != instancedBuffer) {
this.instancedBuffer = instancedBuffer;
if (this.instances != skeletons.size()) {
VertexArrayBuilder format = this.vertexArray.editFormat();
// The instanced buffer has to be redefined each time it changes size, so re-attach it
format.defineVertexBuffer(1, instancedBuffer, 0, 6, 1);
format.setVertexIAttribute(4, 1, 1, VertexArrayBuilder.DataType.UNSIGNED_BYTE, 0); // Overlay Coordinates
format.setVertexIAttribute(5, 1, 1, VertexArrayBuilder.DataType.UNSIGNED_BYTE, 1); // Lightmap Coordinates
format.setVertexAttribute(6, 1, 4, VertexArrayBuilder.DataType.UNSIGNED_BYTE, true, 2); // Color
if (this.instances == 0) {
format.setVertexIAttribute(4, 1, 1, VertexArrayBuilder.DataType.UNSIGNED_BYTE, 0); // Overlay Coordinates
format.setVertexIAttribute(5, 1, 1, VertexArrayBuilder.DataType.UNSIGNED_BYTE, 1); // Lightmap Coordinates
format.setVertexAttribute(6, 1, 4, VertexArrayBuilder.DataType.UNSIGNED_BYTE, true, 2); // Color
}
this.instances = skeletons.size();
}

Skeleton first = skeletons.iterator().next();
Skeleton first = skeletons.getFirst();
int maxDepth = first.getMaxDepth();
if (this.matrixStack == null || this.matrixStack.length < maxDepth) {
this.matrixStack = new Matrix4x3f[maxDepth];
Expand All @@ -93,7 +89,7 @@ public void render(RenderType renderType, List<Matrix4f> transforms, Collection<
}

// Store bone data in buffer
int skeletonDataSize = this.getSkeletonDataSize();
int skeletonDataSize = Skeleton.UNIFORM_STRIDE * this.getSkeletonDataSize();
try (MemoryStack stack = MemoryStack.stackPush()) {
ByteBuffer buffer = stack.malloc(skeletonDataSize);
int offset = 0;
Expand Down Expand Up @@ -121,9 +117,9 @@ public void render(RenderType renderType, List<Matrix4f> transforms, Collection<
shader.setDefaultUniforms(VertexFormat.Mode.TRIANGLES, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix(), Minecraft.getInstance().getWindow());
shader.apply();

Uniform uniform = shader.getUniform("NecromancerMeshSize");
Uniform uniform = shader.getUniform("NecromancerBoneCount");
if (uniform != null) {
glUniform1ui(uniform.getLocation(), skeletonDataSize);
glUniform1ui(uniform.getLocation(), this.boneIds.size());
}
}

Expand All @@ -142,8 +138,8 @@ public VertexArray getVertexArray() {
return this.vertexArray;
}

public int getUniformSize() {
return this.uniformSize;
public int getSkeletonDataSize() {
return this.boneIds.size();
}

public static VertexArray createVertexArray() {
Expand Down Expand Up @@ -311,15 +307,6 @@ public Builder addCube(float xSize, float ySize, float zSize, float xOffset, flo
minX = swap;
}

Vector3f ooo = new Vector3f(minX, minY, minZ);
Vector3f xoo = new Vector3f(maxX, minY, minZ);
Vector3f oyo = new Vector3f(minX, maxY, minZ);
Vector3f ooz = new Vector3f(minX, minY, maxZ);
Vector3f xyo = new Vector3f(maxX, maxY, minZ);
Vector3f oyz = new Vector3f(minX, maxY, maxZ);
Vector3f xoz = new Vector3f(maxX, minY, maxZ);
Vector3f xyz = new Vector3f(maxX, maxY, maxZ);

float eastUStart = uOffset;
float northUStart = uOffset + Mth.floor(zSize);
float westUStart = uOffset + Mth.floor(zSize) + Mth.floor(xSize);
Expand All @@ -330,16 +317,6 @@ public Builder addCube(float xSize, float ySize, float zSize, float xOffset, flo
float sideVStart = vOffset + Mth.floor(zSize);
float sideVEnd = vOffset + Mth.floor(zSize) + Mth.floor(ySize);

// Mesh.Face[] cubeFaces = {
// new Mesh.Face(xoz, ooz, ooo, xoo, u3, v0, u2, v1, this.textureWidth, this.textureHeight, mirrored, Direction.UP),
// new Mesh.Face(xyo, oyo, oyz, xyz, u2, v1, u1, v0, this.textureWidth, this.textureHeight, mirrored, Direction.DOWN),
// new Mesh.Face(ooo, ooz, oyz, oyo, u4, v2, u2, v1, this.textureWidth, this.textureHeight, mirrored, Direction.EAST),
// new Mesh.Face(xoz, xoo, xyo, xyz, u1, v2, u0, v1, this.textureWidth, this.textureHeight, mirrored, Direction.WEST),
// new Mesh.Face(ooz, xoz, xyz, oyz, u5, v2, u4, v1, this.textureWidth, this.textureHeight, mirrored, Direction.NORTH),
// new Mesh.Face(xoo, ooo, oyo, xyo, u2, v2, u1, v1, this.textureWidth, this.textureHeight, mirrored, Direction.SOUTH)};
//
// Collections.addAll(this.faces, cubeFaces);

// Up
this.addVertex(minX, maxY, minZ, northUStart / this.textureWidth, sideVStart / this.textureHeight, 0.0F, 1.0F, 0.0F);
this.addVertex(minX, maxY, maxZ, northUStart / this.textureWidth, topVStart / this.textureHeight, 0.0F, 1.0F, 0.0F);
Expand Down Expand Up @@ -382,32 +359,14 @@ public Builder addCube(float xSize, float ySize, float zSize, float xOffset, flo
this.addVertex(minX, maxY, maxZ, southUStart / this.textureWidth, sideVStart / this.textureHeight, 0.0F, 0.0F, 1.0F);
this.addQuadIndices(this.nextIndex);

// 1,0 0,0 0,1 1,1

// this.vertices = new Mesh.Vertex[]{a, b, c, d};
// this.uvs = new Mesh.UV[] {new Mesh.UV(u1 / textureWidth, v0 / textureHeight), new Mesh.UV(u0 / textureWidth, v0 / textureHeight), new Mesh.UV(u0 / textureWidth, v1 / textureHeight), new Mesh.UV(u1 / textureWidth, v1 / textureHeight)};
// if (mirrored) {
// int i = this.vertices.length;
// for(int j = 0; j < i / 2; ++j) {
// Mesh.Vertex vertex = this.vertices[j];
// Mesh.UV uv = this.uvs[j];
// this.vertices[j] = this.vertices[i - 1 - j];
// this.uvs[j] = this.uvs[i - 1 - j];
// this.vertices[i - 1 - j] = vertex;
// this.uvs[i - 1 - j] = uv;
// }
// }
//
// this.normal = pDirection.step();
// if (mirrored) {
// this.normal.mul(-1.0F, 1.0F, 1.0F);
// }
// this.normal.mul(-1.0F, -1.0F, -1.0F);

return this;
}

public Builder addTri(float x1, float y1, float z1, float u1, float v1, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float normalX, float normalY, float normalZ) {
public Builder addTri(
float x1, float y1, float z1, float u1, float v1,
float x2, float y2, float z2, float u2, float v2,
float x3, float y3, float z3, float u3, float v3,
float normalX, float normalY, float normalZ) {
this.vertices.reserve(72);
this.addVertex(x1, y1, z1, u1, v1, normalX, normalY, normalZ);
this.addVertex(x2, y2, z2, u2, v2, normalX, normalY, normalZ);
Expand Down Expand Up @@ -466,7 +425,7 @@ public Skin build() {
boneIds.put(this.boneNames.get(i), i);
}

return new Skin(this.vertexArray, Object2IntMaps.unmodifiable(boneIds), this.boneNames.size() * Skeleton.UNIFORM_STRIDE);
return new Skin(this.vertexArray, Object2IntMaps.unmodifiable(boneIds));
} finally {
MemoryUtil.memFree(indices);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ private static void updateBlockSize(int skeletonCount, int dataSize) {
boneBlock = ShaderBlock.wrapper(ShaderBlock.BufferBinding.UNIFORM, boneBuffer);
}

long minSize = (long) skeletonCount * dataSize;
long minSize = (long) Skeleton.UNIFORM_STRIDE * skeletonCount * dataSize;
if (boneBlock.getSize() < minSize) {
boneBlock.setSize(minSize);
VeilRenderSystem.renderer().getShaderDefinitions().set("NecromancerBoneCount", Integer.toString(skeletonCount));
VeilRenderSystem.renderer().getShaderDefinitions().set("NECROMANCER_BONE_BUFFER_SIZE", Integer.toString(skeletonCount * dataSize));
if (VeilRenderSystem.directStateAccessSupported()) {
glNamedBufferData(boneBuffer, minSize, GL_DYNAMIC_DRAW);
} else {
Expand Down
33 changes: 33 additions & 0 deletions common/src/main/java/foundry/veil/mixin/fix/MemUtilMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package foundry.veil.mixin.fix;

import org.joml.Matrix3f;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import sun.misc.Unsafe;

@Mixin(targets = "org.joml.MemUtil$MemUtilUnsafe", remap = false)
public class MemUtilMixin {

@Shadow
@Final
public static Unsafe UNSAFE;

@Shadow
@Final
public static long Matrix3f_m00;

/**
* @author Ocelot
* @reason Apply the fix from <a href="https://github.com/JOML-CI/JOML/commit/933eb412bb19ce7b6f98062e1c94449c50d92dca">933eb41</a>
*/
@Overwrite
public static void put3x4(Matrix3f m, long destAddr) {
for (int i = 0; i < 3; i++) {
UNSAFE.putLong(null, destAddr + (i << 4), UNSAFE.getLong(m, Matrix3f_m00 + 12 * i));
UNSAFE.putFloat(null, destAddr + (i << 4) + 8, UNSAFE.getFloat(m, Matrix3f_m00 + 8 + 12 * i));
UNSAFE.putFloat(null, destAddr + (i << 4) + 12, 0.0f);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"vertex": "veil:necromancer/skinned_mesh",
"fragment": "veil:necromancer/skinned_mesh"
"fragment": "veil:necromancer/skinned_mesh",
"definitions": [
{
"NECROMANCER_BONE_BUFFER_SIZE": 1
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct BoneData {
};

layout(std140) uniform NecromancerBones {
BoneData Bones[1]; // TODO set up properly
BoneData Bones[NECROMANCER_BONE_BUFFER_SIZE];
};

uniform sampler2D Sampler1;
Expand All @@ -39,15 +39,15 @@ out vec2 texCoord0;
out vec3 normal;

void main() {
uint index = BoneIndex + NecromancerBoneCount * gl_InstanceID;
mat4 transform = mat4(Bones[index].Transform);
BoneData data = Bones[BoneIndex + NecromancerBoneCount * gl_InstanceID];
mat4 transform = mat4(data.Transform);
transform[3] = vec4(0.0, 0.0, 0.0, 1.0); // Last column is color, so set it to identity
gl_Position = ProjMat * ModelViewMat * transpose(transform) * vec4(Position, 1.0);

vertexDistance = fog_distance(ModelViewMat, Position, FogShape);

vec3 BoneNormal = Bones[index].Normal * Normal;
vertexColor = ModelColor * Bones[index].Transform[3] * minecraft_mix_light(Light0_Direction, Light1_Direction, Normal);
vec3 BoneNormal = data.Normal * Normal;
vertexColor = ModelColor * data.Transform[3] * minecraft_mix_light(Light0_Direction, Light1_Direction, Normal);

ivec2 UV2 = ivec2(PackedLight & 15u, (PackedLight >> 4u) & 15u);
ivec2 UV1 = ivec2(PackedOverlay & 15u, (PackedOverlay >> 4u) & 15u);
Expand Down
15 changes: 15 additions & 0 deletions common/src/main/resources/veil.fix.mixins.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"required": true,
"minVersion": "0.8",
"package": "foundry.veil.mixin.fix",
"compatibilityLevel": "JAVA_21",
"refmap": "${mod_id}.refmap.json",
"mixins": [
"MemUtilMixin"
],
"client": [],
"injectors": {
"defaultRequire": 1
}
}

1 change: 1 addition & 0 deletions fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"mixins": [
"${mod_id}.debug.mixins.json",
"${mod_id}.dynamicbuffer.mixins.json",
"${mod_id}.fix.mixins.json",
"${mod_id}.framebuffer.mixins.json",
"${mod_id}.imgui.mixins.json",
"${mod_id}.necromancer.mixins.json",
Expand Down
12 changes: 7 additions & 5 deletions neoforge/src/main/resources/META-INF/neoforge.mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ description='''${description}'''
config = "${mod_id}.debug.mixins.json"
[[mixins]]
config = "${mod_id}.dynamicbuffer.mixins.json"
[[mixins]]
config = "${mod_id}.fix.mixins.json"
[[mixins]]
config = "${mod_id}.framebuffer.mixins.json"
[[mixins]]
Expand Down Expand Up @@ -48,22 +50,22 @@ description='''${description}'''
[[accessTransformers]]
file="META-INF/accesstransformer.cfg"

[[dependencies.veil]]
[[dependencies.${mod_id}]]
modId = "neoforge"
versionRange = "${neoforge_version_range}"
[[dependencies.veil]]
[[dependencies.${mod_id}]]
modId = "minecraft"
versionRange = "${minecraft_version_range}"
[[dependencies.veil]]
[[dependencies.${mod_id}]]
modId = "rubidium"
type = "incompatible"
[[dependencies.veil]]
[[dependencies.${mod_id}]]
modId = "sodium"
type = "incompatible"
versionRange = "(,${sodium_version})"

# Features are specific properties of the game environment, that you may want to declare you require. This example declares
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
# stop your mod loading on the server for example.
[features.veil]
[features.${mod_id}]
openGLVersion = "[3.2,)"

0 comments on commit 8f5f872

Please sign in to comment.