mirror of
https://github.com/GTNewHorizons/Angelica.git
synced 2026-10-26 14:24:30 +00:00
Refactor Quad, BlockPos, and QuadProvider API
Also optimize static models
This commit is contained in:
1 parent
da8f700068
commit
346a305f1d
49 files changed
+701
-525
No files matched your search
@@ -2,6 +2,10 @@ plugins {
|
||||
id("com.gtnewhorizons.gtnhconvention")
|
||||
}
|
||||
|
||||
minecraft {
|
||||
extraRunJvmArguments.add("-Dangelica.enableTestBlocks=true")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import static com.google.common.math.IntMath.log2;
|
||||
|
||||
public interface BlockPos {
|
||||
|
||||
int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY);
|
||||
int SIZE_BITS_Z = SIZE_BITS_X;
|
||||
int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z;
|
||||
long BITS_X = (1L << SIZE_BITS_X) - 1L;
|
||||
long BITS_Y = (1L << SIZE_BITS_Y) - 1L;
|
||||
long BITS_Z = (1L << SIZE_BITS_Z) - 1L;
|
||||
int BIT_SHIFT_Z = SIZE_BITS_Y;
|
||||
int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z;
|
||||
|
||||
int getX();
|
||||
int getY();
|
||||
int getZ();
|
||||
BlockPosImpl offset(ForgeDirection d);
|
||||
BlockPosImpl down();
|
||||
BlockPosImpl up();
|
||||
long asLong();
|
||||
|
||||
static long asLong(int x, int y, int z) {
|
||||
long l = 0L;
|
||||
l |= ((long) x & BITS_X) << BIT_SHIFT_X;
|
||||
l |= ((long) y & BITS_Y) << 0;
|
||||
l |= ((long) z & BITS_Z) << BIT_SHIFT_Z;
|
||||
return l;
|
||||
}
|
||||
|
||||
public static int unpackLongX(long packedPos) {
|
||||
return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X);
|
||||
}
|
||||
|
||||
public static int unpackLongY(long packedPos) {
|
||||
return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y);
|
||||
}
|
||||
|
||||
public static int unpackLongZ(long packedPos) {
|
||||
return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
public interface MutableBlockPos extends BlockPos {
|
||||
|
||||
MutableBlockPos set(int x, int y, int z);
|
||||
|
||||
MutableBlockPos set(long packedPos);
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface QuadProvider {
|
||||
|
||||
@@ -23,9 +21,23 @@ public interface QuadProvider {
|
||||
*/
|
||||
default int getColor(IBlockAccess world, BlockPos pos, Block block, int meta, Random random) {
|
||||
|
||||
final int cin = block.colorMultiplier(world, pos.x, pos.y, pos.z);
|
||||
final int cin = block.colorMultiplier(world, pos.getX(), pos.getY(), pos.getZ());
|
||||
return (0xFF << 24) | ((cin & B_MASK) << 16) | (cin & G_MASK) | ((cin & R_MASK) >>> 16);
|
||||
}
|
||||
|
||||
List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool);
|
||||
/**
|
||||
* If you need to allocate new quads, set this to true. If true, the quads returned by {@link #getQuads} are
|
||||
* recycled, and you should not keep a reference to them. Example: stone can return a static list every time, but a
|
||||
* modded block which adds or removes quads based on location would need dynamic quads.
|
||||
*/
|
||||
default boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide quads to render. If you need new quads, they should be obtained with the passed supplier and
|
||||
* {@link #isDynamic} overridden to return true. If so, all quads in the list are recycled and references to them
|
||||
* should not be kept.
|
||||
*/
|
||||
List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.gtnewhorizons.angelica.api;
|
||||
|
||||
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable;
|
||||
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface QuadView extends ModelQuadViewMutable {
|
||||
|
||||
boolean isShade();
|
||||
boolean isDeleted();
|
||||
ForgeDirection getFace();
|
||||
void copyFrom(QuadView src);
|
||||
void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags);
|
||||
int[] getRawVertexes();
|
||||
|
||||
/**
|
||||
* Present for compatibility with the Tesselator, not recommended for general use.
|
||||
*/
|
||||
void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ);
|
||||
}
|
||||
+11
-10
@@ -1,8 +1,9 @@
|
||||
package com.gtnewhorizons.angelica.client.renderer;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import com.gtnewhorizons.angelica.glsm.stacks.Vector3dStack;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ITessellatorInstance;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
@@ -39,15 +40,15 @@ public class CapturingTessellator extends Tessellator implements ITessellatorIns
|
||||
private static final MethodHandle sRawBufferSize;
|
||||
private static final MethodHandle gRawBufferSize;
|
||||
private final BlockRenderer.Flags FLAGS = new BlockRenderer.Flags(true, true, true, true);
|
||||
private final ObjectPooler<Quad> quadBuf = new ObjectPooler<>(Quad::new);
|
||||
private final List<Quad> collectedQuads = new ObjectArrayList<>();
|
||||
private final ObjectPooler<QuadView> quadBuf = new ObjectPooler<>(Quad::new);
|
||||
private final List<QuadView> collectedQuads = new ObjectArrayList<>();
|
||||
|
||||
// Any offset we need to the Tesselator's offset!
|
||||
private final BlockPos offset = new BlockPos();
|
||||
private final BlockPosImpl offset = new BlockPosImpl();
|
||||
|
||||
private final Vector3dStack storedTranslation = new Vector3dStack();
|
||||
|
||||
public void setOffset(BlockPos pos) {
|
||||
public void setOffset(BlockPosImpl pos) {
|
||||
this.offset.set(pos);
|
||||
}
|
||||
public void resetOffset() {
|
||||
@@ -93,10 +94,10 @@ public class CapturingTessellator extends Tessellator implements ITessellatorIns
|
||||
|
||||
|
||||
for(int quadI = 0; quadI < this.vertexCount / verticesPerPrimitive; quadI++) {
|
||||
final Quad quad = quadBuf.getInstance();
|
||||
final QuadView quad = quadBuf.getInstance();
|
||||
quad.setState(this.rawBuffer, quadI * (verticesPerPrimitive * 8), FLAGS, this.drawMode, -offset.x, -offset.y, -offset.z);
|
||||
|
||||
if(quad.deleted) {
|
||||
if(quad.isDeleted()) {
|
||||
quadBuf.releaseInstance(quad);
|
||||
} else {
|
||||
this.collectedQuads.add(quad);
|
||||
@@ -115,7 +116,7 @@ public class CapturingTessellator extends Tessellator implements ITessellatorIns
|
||||
}
|
||||
|
||||
|
||||
public List<Quad> getQuads() {
|
||||
public List<QuadView> getQuads() {
|
||||
return collectedQuads;
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ public class CapturingTessellator extends Tessellator implements ITessellatorIns
|
||||
this.collectedQuads.clear();
|
||||
}
|
||||
|
||||
public static ByteBuffer quadsToBuffer(List<Quad> quads, VertexFormat format) {
|
||||
public static ByteBuffer quadsToBuffer(List<QuadView> quads, VertexFormat format) {
|
||||
if(!format.canWriteQuads()) {
|
||||
throw new IllegalStateException("Vertex format has no quad writer: " + format);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package com.gtnewhorizons.angelica.common;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.json.JsonModel;
|
||||
import com.gtnewhorizons.angelica.models.json.Loader;
|
||||
import com.gtnewhorizons.angelica.models.json.Variant;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
@@ -19,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BlockTest extends Block implements QuadProvider {
|
||||
|
||||
@@ -48,7 +48,7 @@ public class BlockTest extends Block implements QuadProvider {
|
||||
false
|
||||
),
|
||||
};
|
||||
private static final List<Quad> EMPTY = ObjectImmutableList.of();
|
||||
private static final List<QuadView> EMPTY = ObjectImmutableList.of();
|
||||
private static final JsonModel[] model = new JsonModel[4];
|
||||
|
||||
public BlockTest() {
|
||||
@@ -78,7 +78,7 @@ public class BlockTest extends Block implements QuadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
|
||||
if (meta < 2 || meta > 5) meta = 2;
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import static com.google.common.math.IntMath.log2;
|
||||
|
||||
// Should we keep this?
|
||||
public class BlockPos extends Vector3i {
|
||||
|
||||
private static final int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY);
|
||||
private static final int SIZE_BITS_Z = SIZE_BITS_X;
|
||||
private static final int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z;
|
||||
private static final long BITS_X = (1L << SIZE_BITS_X) - 1L;
|
||||
private static final long BITS_Y = (1L << SIZE_BITS_Y) - 1L;
|
||||
private static final long BITS_Z = (1L << SIZE_BITS_Z) - 1L;
|
||||
private static final int BIT_SHIFT_Z = SIZE_BITS_Y;
|
||||
private static final int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z;
|
||||
|
||||
public BlockPos() {
|
||||
super();
|
||||
}
|
||||
public BlockPos(int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
public BlockPos(ChunkPosition chunkPosition) {
|
||||
super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
public BlockPos set(int x, int y, int z) {
|
||||
super.set(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does NOT mutate the BlockPos
|
||||
*/
|
||||
public BlockPos offset(ForgeDirection d) {
|
||||
return new BlockPos(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does NOT mutate the BlockPos
|
||||
*/
|
||||
public BlockPos down() {
|
||||
return offset(ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does NOT mutate the BlockPos
|
||||
*/
|
||||
public BlockPos up() {
|
||||
return offset(ForgeDirection.UP);
|
||||
}
|
||||
|
||||
public long asLong() {
|
||||
return asLong(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
public static long asLong(int x, int y, int z) {
|
||||
long l = 0L;
|
||||
l |= ((long)x & BITS_X) << BIT_SHIFT_X;
|
||||
l |= ((long)y & BITS_Y) << 0;
|
||||
l |= ((long)z & BITS_Z) << BIT_SHIFT_Z;
|
||||
return l;
|
||||
}
|
||||
|
||||
public BlockPos set(long packedPos) {
|
||||
return set(unpackLongX(packedPos), unpackLongY(packedPos), unpackLongZ(packedPos));
|
||||
}
|
||||
|
||||
public static int unpackLongX(long packedPos) {
|
||||
return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X);
|
||||
}
|
||||
|
||||
public static int unpackLongY(long packedPos) {
|
||||
return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y);
|
||||
}
|
||||
|
||||
public static int unpackLongZ(long packedPos) {
|
||||
return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z);
|
||||
}
|
||||
|
||||
public static class Mutable extends BlockPos {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.MutableBlockPos;
|
||||
import net.minecraft.world.ChunkPosition;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongX;
|
||||
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongY;
|
||||
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongZ;
|
||||
|
||||
// Should we keep this?
|
||||
public class BlockPosImpl extends Vector3i implements MutableBlockPos {
|
||||
|
||||
public BlockPosImpl() {
|
||||
super();
|
||||
}
|
||||
public BlockPosImpl(int x, int y, int z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
public BlockPosImpl(ChunkPosition chunkPosition) {
|
||||
super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
@Override
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
@Override
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl offset(ForgeDirection d) {
|
||||
return new BlockPosImpl(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl down() {
|
||||
return offset(ForgeDirection.DOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl up() {
|
||||
return offset(ForgeDirection.UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long asLong() {
|
||||
return BlockPos.asLong(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl set(int x, int y, int z) {
|
||||
super.set(x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosImpl set(long packedPos) {
|
||||
return set(unpackLongX(packedPos), unpackLongY(packedPos), unpackLongZ(packedPos));
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import org.joml.Vector4f;
|
||||
@Getter
|
||||
public class Camera {
|
||||
final Vector3d pos = new Vector3d();
|
||||
final BlockPos.Mutable blockPos = new BlockPos.Mutable();
|
||||
final BlockPosImpl blockPos = new BlockPosImpl();
|
||||
float pitch;
|
||||
float yaw;
|
||||
EntityLivingBase entity;
|
||||
|
||||
+2
-2
@@ -36,12 +36,12 @@ public class ChunkOcclusionDataBuilder {
|
||||
}
|
||||
private int openCount = 4096;
|
||||
|
||||
public void markClosed(BlockPos pos) {
|
||||
public void markClosed(BlockPosImpl pos) {
|
||||
this.closed.set(pack(pos), true);
|
||||
--this.openCount;
|
||||
}
|
||||
|
||||
private static int pack(BlockPos pos) {
|
||||
private static int pack(BlockPosImpl pos) {
|
||||
return pack(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public class ChunkPos {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public ChunkPos(BlockPos pos) {
|
||||
public ChunkPos(BlockPosImpl pos) {
|
||||
this.x = pos.getX() >> 4;
|
||||
this.z = pos.getZ() >> 4;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ChunkSectionPos extends Vector3i {
|
||||
return new ChunkSectionPos(x, y, z);
|
||||
}
|
||||
|
||||
public static ChunkSectionPos from(BlockPos pos) {
|
||||
public static ChunkSectionPos from(BlockPosImpl pos) {
|
||||
return new ChunkSectionPos(getSectionCoord(pos.getX()), getSectionCoord(pos.getY()), getSectionCoord(pos.getZ()));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.compat.mojang;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
@@ -79,7 +79,7 @@ public class VertexFormat {
|
||||
return quadWriter != null;
|
||||
}
|
||||
|
||||
public void writeQuad(Quad quad, ByteBuffer byteBuffer) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer byteBuffer) {
|
||||
if(quadWriter == null) {
|
||||
throw new IllegalStateException("No quad writer set");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface IWriteQuads {
|
||||
void writeQuad(Quad quad, ByteBuffer buf);
|
||||
void writeQuad(QuadView quad, ByteBuffer buf);
|
||||
}
|
||||
@@ -1,218 +0,0 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
|
||||
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Quad implements ModelQuadView {
|
||||
// Adapted from Neodymium
|
||||
|
||||
private final static int DEFAULT_BRIGHTNESS = 15 << 20 | 15 << 4;
|
||||
private final static int DEFAULT_COLOR = 0xFFFFFFFF;
|
||||
|
||||
public float[] xs = new float[4];
|
||||
public float[] ys = new float[4];
|
||||
public float[] zs = new float[4];
|
||||
public float[] us = new float[4];
|
||||
public float[] vs = new float[4];
|
||||
public int[] cs = new int[4];
|
||||
public int[] ns = new int[4];
|
||||
public int[] bs = new int[4];
|
||||
|
||||
public boolean deleted;
|
||||
|
||||
private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f();
|
||||
|
||||
@Getter
|
||||
private boolean shade;
|
||||
private int cachedFlags;
|
||||
@Getter
|
||||
private ForgeDirection face;
|
||||
private int colorIndex = -1;
|
||||
|
||||
public int[] getColors() {
|
||||
return this.cs;
|
||||
}
|
||||
|
||||
/** Returns the face, forced to take one of 6 directions to mirror the behavior of baked quads in 1.16.5. */
|
||||
@Override
|
||||
public ForgeDirection getLightFace() {
|
||||
return this.face != ForgeDirection.UNKNOWN ? this.face : ForgeDirection.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX(int idx) {
|
||||
return xs[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getY(int idx) {
|
||||
return ys[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getZ(int idx) {
|
||||
return zs[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(int idx) {
|
||||
return cs[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexU(int idx) {
|
||||
return us[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexV(int idx) {
|
||||
return vs[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlags() {
|
||||
return this.cachedFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int idx) {
|
||||
return bs[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNormal(int idx) {
|
||||
return ns[idx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColorIndex() {
|
||||
return colorIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite rubidium$getSprite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void copyFrom(Quad quad) {
|
||||
|
||||
System.arraycopy(quad.xs, 0, this.xs, 0, 4);
|
||||
System.arraycopy(quad.ys, 0, this.ys, 0, 4);
|
||||
System.arraycopy(quad.zs, 0, this.zs, 0, 4);
|
||||
|
||||
System.arraycopy(quad.us, 0, this.us, 0, 4);
|
||||
System.arraycopy(quad.vs, 0, this.vs, 0, 4);
|
||||
|
||||
System.arraycopy(quad.cs, 0, this.cs, 0, 4);
|
||||
System.arraycopy(quad.ns, 0, this.ns, 0, 4);
|
||||
System.arraycopy(quad.bs, 0, this.bs, 0, 4);
|
||||
|
||||
this.deleted = quad.deleted;
|
||||
this.shade = quad.shade;
|
||||
this.cachedFlags = quad.cachedFlags;
|
||||
this.face = quad.face;
|
||||
this.colorIndex = quad.colorIndex;
|
||||
}
|
||||
|
||||
public void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags) {
|
||||
|
||||
int i = 0;
|
||||
for(int vi = 0; vi < 4; vi++) {
|
||||
|
||||
xs[vi] = Float.intBitsToFloat(data[i + 0]);
|
||||
ys[vi] = Float.intBitsToFloat(data[i + 1]);
|
||||
zs[vi] = Float.intBitsToFloat(data[i + 2]);
|
||||
|
||||
us[vi] = Float.intBitsToFloat(data[i + 3]);
|
||||
vs[vi] = Float.intBitsToFloat(data[i + 4]);
|
||||
|
||||
cs[vi] = data[i + 5];
|
||||
ns[vi] = data[i + 6];
|
||||
bs[vi] = data[i + 7];
|
||||
|
||||
i += 8;
|
||||
}
|
||||
|
||||
this.shade = shade;
|
||||
this.deleted = false;
|
||||
this.face = face;
|
||||
this.colorIndex = colorIndex;
|
||||
this.cachedFlags = flags;
|
||||
}
|
||||
|
||||
private void read(int[] rawBuffer, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, BlockRenderer.Flags flags) {
|
||||
final int vertices = drawMode == GL11.GL_TRIANGLES ? 3 : 4;
|
||||
int i = offset;
|
||||
for(int vi = 0; vi < vertices; vi++) {
|
||||
|
||||
xs[vi] = Float.intBitsToFloat(rawBuffer[i + 0]) + offsetX;
|
||||
ys[vi] = Float.intBitsToFloat(rawBuffer[i + 1]) + offsetY;
|
||||
zs[vi] = Float.intBitsToFloat(rawBuffer[i + 2]) + offsetZ;
|
||||
|
||||
us[vi] = Float.intBitsToFloat(rawBuffer[i + 3]);
|
||||
vs[vi] = Float.intBitsToFloat(rawBuffer[i + 4]);
|
||||
|
||||
cs[vi] = flags.hasColor ? rawBuffer[i + 5] : DEFAULT_COLOR;
|
||||
ns[vi] = flags.hasNormals ? rawBuffer[i + 6] : 0;
|
||||
bs[vi] = flags.hasBrightness ? rawBuffer[i + 7] : DEFAULT_BRIGHTNESS;
|
||||
|
||||
i += 8;
|
||||
}
|
||||
|
||||
// sus
|
||||
this.shade = flags.hasBrightness;
|
||||
|
||||
if(vertices == 3) {
|
||||
|
||||
// Quadrangulate!
|
||||
xs[3] = xs[2];
|
||||
ys[3] = ys[2];
|
||||
zs[3] = zs[2];
|
||||
|
||||
us[3] = us[2];
|
||||
vs[3] = vs[2];
|
||||
|
||||
bs[3] = bs[2];
|
||||
cs[3] = cs[2];
|
||||
ns[3] = ns[2];
|
||||
}
|
||||
}
|
||||
|
||||
public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) {
|
||||
deleted = false;
|
||||
|
||||
read(rawBuffer, offset, offsetX, offsetY, offsetZ, drawMode, flags);
|
||||
|
||||
if(xs[0] == xs[1] && xs[1] == xs[2] && xs[2] == xs[3] && ys[0] == ys[1] && ys[1] == ys[2] && ys[2] == ys[3]) {
|
||||
// ignore empty quads (e.g. alpha pass of EnderIO item conduits)
|
||||
deleted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
vectorA.set(xs[1] - xs[0], ys[1] - ys[0], zs[1] - zs[0]);
|
||||
vectorB.set(xs[2] - xs[1], ys[2] - ys[1], zs[2] - zs[1]);
|
||||
vectorA.cross(vectorB, vectorC);
|
||||
|
||||
this.face = ModelQuadFacing.toDirection(ModelQuadFacing.fromVector(vectorC));
|
||||
this.cachedFlags = ModelQuadFlags.getQuadFlags(this);
|
||||
}
|
||||
|
||||
public static boolean isValid(Quad q) {
|
||||
return q != null && !q.deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(Locale.ENGLISH, "%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]", deleted ? "XXX " : "", xs[0], ys[0], zs[0], xs[1], ys[1], zs[1], xs[2], ys[2], zs[2], xs[3], ys[3], zs[3]);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ItemVBOQuadWriter implements IWriteQuads {
|
||||
this.direct = direct;
|
||||
}
|
||||
@Override
|
||||
public void writeQuad(Quad quad, ByteBuffer buf) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer buf) {
|
||||
if(direct) {
|
||||
writeQuadDirect(quad, buf);
|
||||
} else {
|
||||
@@ -25,11 +25,11 @@ public class ItemVBOQuadWriter implements IWriteQuads {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
|
||||
throw new UnsupportedOperationException("Direct mode not supported yet");
|
||||
}
|
||||
|
||||
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
|
||||
for(int idx = 0; idx < 4; ++idx) {
|
||||
// Position
|
||||
buf.putFloat(quad.getX(idx));
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PositionColorTextureQuadWriter implements IWriteQuads {
|
||||
this.direct = direct;
|
||||
}
|
||||
@Override
|
||||
public void writeQuad(Quad quad, ByteBuffer buf) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer buf) {
|
||||
if(direct) {
|
||||
writeQuadDirect(quad, buf);
|
||||
} else {
|
||||
@@ -25,11 +25,11 @@ public class PositionColorTextureQuadWriter implements IWriteQuads {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
|
||||
throw new UnsupportedOperationException("Direct mode not supported yet");
|
||||
}
|
||||
|
||||
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
|
||||
for(int idx = 0; idx < 4; ++idx) {
|
||||
// Position
|
||||
buf.putFloat(quad.getX(idx));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PositionQuadWriter implements IWriteQuads {
|
||||
this.direct = direct;
|
||||
}
|
||||
@Override
|
||||
public void writeQuad(Quad quad, ByteBuffer buf) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer buf) {
|
||||
if(direct) {
|
||||
writeQuadDirect(quad, buf);
|
||||
} else {
|
||||
@@ -25,11 +25,11 @@ public class PositionQuadWriter implements IWriteQuads {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
|
||||
throw new UnsupportedOperationException("Direct mode not supported yet");
|
||||
}
|
||||
|
||||
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
|
||||
for(int idx = 0; idx < 4; ++idx) {
|
||||
// Position
|
||||
buf.putFloat(quad.getX(idx));
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PositionTextureColorQuadWriter implements IWriteQuads {
|
||||
this.direct = direct;
|
||||
}
|
||||
@Override
|
||||
public void writeQuad(Quad quad, ByteBuffer buf) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer buf) {
|
||||
if(direct) {
|
||||
writeQuadDirect(quad, buf);
|
||||
} else {
|
||||
@@ -25,11 +25,11 @@ public class PositionTextureColorQuadWriter implements IWriteQuads {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
|
||||
throw new UnsupportedOperationException("Direct mode not supported yet");
|
||||
}
|
||||
|
||||
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
|
||||
for(int idx = 0; idx < 4; ++idx) {
|
||||
// Position
|
||||
buf.putFloat(quad.getX(idx));
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.compat.nd.writers;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PositionTextureQuadWriter implements IWriteQuads {
|
||||
this.direct = direct;
|
||||
}
|
||||
@Override
|
||||
public void writeQuad(Quad quad, ByteBuffer buf) {
|
||||
public void writeQuad(QuadView quad, ByteBuffer buf) {
|
||||
if(direct) {
|
||||
writeQuadDirect(quad, buf);
|
||||
} else {
|
||||
@@ -25,11 +25,11 @@ public class PositionTextureQuadWriter implements IWriteQuads {
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeQuadDirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
|
||||
throw new UnsupportedOperationException("Direct mode not supported yet");
|
||||
}
|
||||
|
||||
protected void writeQuadIndirect(Quad quad, ByteBuffer buf) {
|
||||
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
|
||||
for(int idx = 0; idx < 4; ++idx) {
|
||||
// Position
|
||||
buf.putFloat(quad.getX(idx));
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package com.gtnewhorizons.angelica.glsm;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexBuffer;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class TessellatorManager {
|
||||
private static final ThreadLocal<CapturingTessellator> capturingTessellator = ThreadLocal.withInitial(CapturingTessellator::new);
|
||||
@@ -51,7 +50,7 @@ public class TessellatorManager {
|
||||
* Stop the CapturingTessellator and return the pooled quads. The quads are valid until clearQuads() is
|
||||
* called on the CapturingTesselator, which must be done before starting capturing again.
|
||||
*/
|
||||
public static List<Quad> stopCapturingToPooledQuads() {
|
||||
public static List<QuadView> stopCapturingToPooledQuads() {
|
||||
if(!currentlyCapturing.get()) throw new IllegalStateException("Tried to stop capturing when not capturing!");
|
||||
currentlyCapturing.set(false);
|
||||
final CapturingTessellator tess = capturingTessellator.get();
|
||||
@@ -59,7 +58,7 @@ public class TessellatorManager {
|
||||
// Be sure we got all the quads
|
||||
if(tess.isDrawing) tess.draw();
|
||||
|
||||
final List<Quad> quads = tess.getQuads();
|
||||
final List<QuadView> quads = tess.getQuads();
|
||||
tess.discard();
|
||||
tess.restoreTranslation();
|
||||
|
||||
|
||||
+9
-6
@@ -1,25 +1,28 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockAir.class)
|
||||
public abstract class MixinBlockAir implements QuadProvider {
|
||||
|
||||
private static List<Quad> quads = ObjectImmutableList.of();
|
||||
@Unique
|
||||
private static final List<QuadView> angelica$EMPTY = ObjectImmutableList.of();
|
||||
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
return quads;
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return angelica$EMPTY;
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -1,9 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLeaves;
|
||||
import net.minecraft.block.material.Material;
|
||||
@@ -13,13 +12,20 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.gtnewhorizons.angelica.models.CubeModel.INSTANCE;
|
||||
|
||||
@Mixin(BlockLeaves.class)
|
||||
public abstract class MixinBlockLeaves extends Block implements QuadProvider {
|
||||
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -1,10 +1,9 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.VanillaModels;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockStone;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
@@ -13,12 +12,13 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockStone.class)
|
||||
public abstract class MixinBlockStone implements QuadProvider {
|
||||
|
||||
// TODO: Use modern model API
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return VanillaModels.stoneModel.getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,10 +1,9 @@
|
||||
package com.gtnewhorizons.angelica.mixins.early.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.models.CubeModel;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockWorkbench;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
@@ -13,12 +12,13 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(BlockWorkbench.class)
|
||||
public class MixinBlockWorkbench implements QuadProvider {
|
||||
|
||||
// TODO: Use modern model API
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
return CubeModel.INSTANCE.get().getQuads(world, pos, block, meta, dir, random, color, quadPool);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.gtnewhorizons.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -13,6 +12,7 @@ import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CubeModel implements QuadProvider {
|
||||
|
||||
@@ -23,8 +23,8 @@ public class CubeModel implements QuadProvider {
|
||||
|
||||
public static final ThreadLocal<CubeModel> INSTANCE = ThreadLocal.withInitial(CubeModel::new);
|
||||
private final NdQuadBuilder builder = new NdQuadBuilder();
|
||||
private static final List<Quad> EMPTY = ObjectImmutableList.of();
|
||||
private final List<Quad> ONE = new ObjectArrayList<>(1);
|
||||
private static final List<QuadView> EMPTY = ObjectImmutableList.of();
|
||||
private final List<QuadView> ONE = new ObjectArrayList<>(1);
|
||||
|
||||
public CubeModel() {
|
||||
|
||||
@@ -32,7 +32,12 @@ public class CubeModel implements QuadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
public boolean isDynamic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
|
||||
if (dir == ForgeDirection.UNKNOWN)
|
||||
return EMPTY;
|
||||
@@ -43,7 +48,7 @@ public class CubeModel implements QuadProvider {
|
||||
|
||||
this.builder.color(color, color, color, color);
|
||||
|
||||
ONE.set(0, this.builder.build(quadPool.getInstance()));
|
||||
ONE.set(0, this.builder.build(quadPool.get()));
|
||||
return ONE;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.Axis;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gtnewhorizons.angelica.models;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import lombok.Getter;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
|
||||
@@ -16,18 +17,6 @@ import java.util.Arrays;
|
||||
|
||||
public class NdQuadBuilder implements ModelQuadView {
|
||||
|
||||
// x, y, z, u, v, color, normal, lightmap
|
||||
public static final int INTS_PER_VERTEX = 8;
|
||||
public static final int QUAD_STRIDE = INTS_PER_VERTEX * 4;
|
||||
public static final int X_INDEX = 0;
|
||||
public static final int Y_INDEX = 1;
|
||||
public static final int Z_INDEX = 2;
|
||||
public static final int U_INDEX = 3;
|
||||
public static final int V_INDEX = 4;
|
||||
public static final int COLOR_INDEX = 5;
|
||||
public static final int NORMAL_INDEX = 6;
|
||||
public static final int LIGHTMAP_INDEX = 7;
|
||||
|
||||
/**
|
||||
* Causes texture to appear with no rotation.
|
||||
* Pass in bakeFlags parameter to {@link #spriteBake(IIcon, int)}.
|
||||
@@ -99,7 +88,7 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
private ForgeDirection lightFace = ForgeDirection.UP;
|
||||
// It's called a header, but because I'm lazy it's at the end
|
||||
// The header is an int with flags -------- -------- -------- -GGGNNNN, then an int for the normal
|
||||
private final int[] data = new int[QUAD_STRIDE];
|
||||
private final int[] data = new int[Quad.QUAD_STRIDE];
|
||||
private int geometryFlags = 0;
|
||||
private boolean isGeometryInvalid = true;
|
||||
private int tag = 0;
|
||||
@@ -111,7 +100,7 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
/**
|
||||
* Dumps to {@param out} and returns it.
|
||||
*/
|
||||
public Quad build(Quad out) {
|
||||
public QuadView build(QuadView out) {
|
||||
|
||||
// FRAPI does this late, but we need to do it before baking to Nd quads
|
||||
this.computeGeometry();
|
||||
@@ -137,7 +126,7 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
* Set vertex color in ARGB format (0xAARRGGBB).
|
||||
*/
|
||||
public void color(int vertexIndex, int color) {
|
||||
data[vertexIndex * INTS_PER_VERTEX + COLOR_INDEX] = color;
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.COLOR_INDEX] = color;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,18 +236,18 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
*/
|
||||
public void pos(int vertexIndex, float x, float y, float z) {
|
||||
|
||||
data[vertexIndex * INTS_PER_VERTEX + X_INDEX] = Float.floatToRawIntBits(x);
|
||||
data[vertexIndex * INTS_PER_VERTEX + Y_INDEX] = Float.floatToRawIntBits(y);
|
||||
data[vertexIndex * INTS_PER_VERTEX + Z_INDEX] = Float.floatToRawIntBits(z);
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX] = Float.floatToRawIntBits(x);
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX] = Float.floatToRawIntBits(y);
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX] = Float.floatToRawIntBits(z);
|
||||
isGeometryInvalid = true;
|
||||
}
|
||||
|
||||
public Vector3f pos(int vertexIndex) {
|
||||
|
||||
return new Vector3f(
|
||||
Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX]),
|
||||
Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Y_INDEX]),
|
||||
Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Z_INDEX])
|
||||
Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX]),
|
||||
Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX]),
|
||||
Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX])
|
||||
);
|
||||
}
|
||||
|
||||
@@ -266,7 +255,7 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
* Convenience: access x, y, z by index 0-2.
|
||||
*/
|
||||
float posByIndex(int vertexIndex, int coordinateIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX + coordinateIndex]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX + coordinateIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,48 +354,48 @@ public class NdQuadBuilder implements ModelQuadView {
|
||||
*/
|
||||
public void uv(int vertexIndex, float u, float v) {
|
||||
|
||||
data[vertexIndex * INTS_PER_VERTEX + U_INDEX] = Float.floatToRawIntBits(u);
|
||||
data[vertexIndex * INTS_PER_VERTEX + V_INDEX] = Float.floatToRawIntBits(v);
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.U_INDEX] = Float.floatToRawIntBits(u);
|
||||
data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.V_INDEX] = Float.floatToRawIntBits(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + X_INDEX]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.X_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getY(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Y_INDEX]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Y_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getZ(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + Z_INDEX]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.Z_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexU(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + U_INDEX]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.U_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexV(int vertexIndex) {
|
||||
return Float.intBitsToFloat(data[vertexIndex * INTS_PER_VERTEX + V_INDEX]);
|
||||
return Float.intBitsToFloat(data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.V_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(int vertexIndex) {
|
||||
return this.data[vertexIndex * INTS_PER_VERTEX + COLOR_INDEX];
|
||||
return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.COLOR_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNormal(int vertexIndex) {
|
||||
return this.data[vertexIndex * INTS_PER_VERTEX + NORMAL_INDEX];
|
||||
return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.NORMAL_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int vertexIndex) {
|
||||
return this.data[vertexIndex * INTS_PER_VERTEX + LIGHTMAP_INDEX];
|
||||
return this.data[vertexIndex * Quad.INTS_PER_VERTEX + Quad.LIGHTMAP_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,13 +6,13 @@ import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.Axis;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import com.gtnewhorizons.angelica.models.NdQuadBuilder;
|
||||
import com.gtnewhorizons.angelica.utils.DirUtil;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
import it.unimi.dsi.fastutil.Function;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
@@ -32,6 +32,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.gtnewhorizons.angelica.utils.JsonUtil.*;
|
||||
import static me.jellysquid.mods.sodium.common.util.DirectionUtil.ALL_DIRECTIONS;
|
||||
@@ -47,9 +48,9 @@ public class JsonModel implements QuadProvider {
|
||||
private final Map<ModelDisplay.Position, ModelDisplay> display;
|
||||
private final Map<String, String> textures;
|
||||
private List<ModelElement> elements;
|
||||
private List<Quad> allQuadStore = new ObjectArrayList<>();
|
||||
private final Map<ForgeDirection, List<Quad>> sidedQuadStore = new Object2ObjectOpenHashMap<>();
|
||||
private static final List<Quad> EMPTY = ObjectImmutableList.of();
|
||||
private List<QuadView> allQuadStore = new ObjectArrayList<>();
|
||||
private final Map<ForgeDirection, List<QuadView>> sidedQuadStore = new Object2ObjectOpenHashMap<>();
|
||||
private static final List<QuadView> EMPTY = ObjectImmutableList.of();
|
||||
|
||||
JsonModel(@Nullable ResourceLocation parentId, boolean useAO, Map<ModelDisplay.Position, ModelDisplay> display, Map<String, String> textures, List<ModelElement> elements) {
|
||||
this.parentId = parentId;
|
||||
@@ -136,7 +137,7 @@ public class JsonModel implements QuadProvider {
|
||||
builder.mat.setAO(this.useAO);
|
||||
|
||||
// Bake and add it
|
||||
final Quad q = builder.build(new Quad());
|
||||
final QuadView q = builder.build(new Quad());
|
||||
this.allQuadStore.add(q);
|
||||
this.sidedQuadStore.computeIfAbsent(f.getCullFace(),
|
||||
o -> new ObjectArrayList<>()).add(q);
|
||||
@@ -147,7 +148,7 @@ public class JsonModel implements QuadProvider {
|
||||
this.allQuadStore = new ObjectImmutableList<>(this.allQuadStore);
|
||||
for (ForgeDirection f : ALL_DIRECTIONS) {
|
||||
|
||||
List<Quad> l = this.sidedQuadStore.computeIfAbsent(f, o -> EMPTY);
|
||||
List<QuadView> l = this.sidedQuadStore.computeIfAbsent(f, o -> EMPTY);
|
||||
if (!l.isEmpty())
|
||||
this.sidedQuadStore.put(f, new ObjectImmutableList<>(l));
|
||||
}
|
||||
@@ -158,19 +159,9 @@ public class JsonModel implements QuadProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Quad> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, ObjectPooler<Quad> quadPool) {
|
||||
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
|
||||
|
||||
final List<Quad> src = this.sidedQuadStore.getOrDefault(dir, EMPTY);
|
||||
final List<Quad> ret = new ObjectArrayList<>(src.size());
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < src.size(); ++i) {
|
||||
final Quad q = quadPool.getInstance();
|
||||
q.copyFrom(src.get(i));
|
||||
ret.add(q);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return this.sidedQuadStore.getOrDefault(dir, EMPTY);
|
||||
}
|
||||
|
||||
public void resolveParents(Function<ResourceLocation, JsonModel> modelLoader) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.EnumSkyBlock;
|
||||
@@ -46,7 +46,7 @@ public class EntityLighter {
|
||||
double sl = 0;
|
||||
double bl = 0;
|
||||
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
BlockPosImpl pos = new BlockPosImpl();
|
||||
|
||||
// Iterate over every block in the sampling volume
|
||||
for (int bX = bMinX; bX < bMaxX; bX++) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import me.jellysquid.mods.sodium.client.model.light.data.QuadLightData;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
@@ -18,5 +18,5 @@ public interface LightPipeline {
|
||||
* @param face The pre-computed facing vector of the quad
|
||||
* @param shade True if the block is shaded by ambient occlusion
|
||||
*/
|
||||
void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade);
|
||||
void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade);
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light.cache;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.api.BlockPos;
|
||||
import it.unimi.dsi.fastutil.longs.Long2LongLinkedOpenHashMap;
|
||||
import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess;
|
||||
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light.data;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import me.jellysquid.mods.sodium.client.util.StateUtil;
|
||||
import me.jellysquid.mods.sodium.client.world.WorldSlice;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -22,7 +22,7 @@ import net.minecraftforge.common.util.ForgeDirection;
|
||||
* You can use the various static pack/unpack methods to extract these values in a usable format.
|
||||
*/
|
||||
public abstract class LightDataAccess {
|
||||
private final BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
private final BlockPosImpl pos = new BlockPosImpl();
|
||||
protected WorldSlice world;
|
||||
|
||||
public long get(int x, int y, int z, ForgeDirection d1, ForgeDirection d2) {
|
||||
@@ -33,11 +33,11 @@ public abstract class LightDataAccess {
|
||||
return this.get(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ);
|
||||
}
|
||||
|
||||
public long get(BlockPos pos, ForgeDirection dir) {
|
||||
public long get(BlockPosImpl pos, ForgeDirection dir) {
|
||||
return this.get(pos.x, pos.y, pos.z, dir);
|
||||
}
|
||||
|
||||
public long get(BlockPos pos) {
|
||||
public long get(BlockPosImpl pos) {
|
||||
return this.get(pos.x, pos.y, pos.getZ());
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light.flat;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import me.jellysquid.mods.sodium.client.model.light.LightPipeline;
|
||||
import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess;
|
||||
@@ -27,7 +27,7 @@ public class FlatLightPipeline implements LightPipeline {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) {
|
||||
public void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) {
|
||||
int lightmap;
|
||||
|
||||
// To match vanilla behavior, use the cull face if it exists/is available
|
||||
@@ -57,7 +57,7 @@ public class FlatLightPipeline implements LightPipeline {
|
||||
* behind tinted glass. {@link LightDataAccess} cannot efficiently store lightmaps computed with
|
||||
* inconsistent values so this method exists to mirror vanilla behavior as closely as possible.
|
||||
*/
|
||||
private int getOffsetLightmap(BlockPos pos, ForgeDirection face) {
|
||||
private int getOffsetLightmap(BlockPosImpl pos, ForgeDirection face) {
|
||||
int lightmap = LightDataAccess.unpackLM(this.lightCache.get(pos, face));
|
||||
// If the block light is not 15 (max)...
|
||||
if ((lightmap & 0xF0) != 0xF0) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light.smooth;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
@@ -18,7 +18,7 @@ class AoFaceData {
|
||||
|
||||
private int flags;
|
||||
|
||||
public void initLightData(LightDataAccess cache, BlockPos pos, ForgeDirection direction, boolean offset) {
|
||||
public void initLightData(LightDataAccess cache, BlockPosImpl pos, ForgeDirection direction, boolean offset) {
|
||||
final int x = pos.x;
|
||||
final int y = pos.y;
|
||||
final int z = pos.z;
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
package me.jellysquid.mods.sodium.client.model.light.smooth;
|
||||
|
||||
import com.google.common.math.DoubleMath;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import me.jellysquid.mods.sodium.client.model.light.LightPipeline;
|
||||
import me.jellysquid.mods.sodium.client.model.light.data.LightDataAccess;
|
||||
@@ -69,7 +69,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(ModelQuadView quad, BlockPos pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) {
|
||||
public void calculate(ModelQuadView quad, BlockPosImpl pos, QuadLightData out, ForgeDirection cullFace, ForgeDirection face, boolean shade) {
|
||||
this.updateCachedData(pos.asLong());
|
||||
|
||||
int flags = quad.getFlags();
|
||||
@@ -101,7 +101,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
* have two contributing sides.
|
||||
* Flags: IS_ALIGNED, !IS_PARTIAL
|
||||
*/
|
||||
private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPos pos, ForgeDirection dir, QuadLightData out) {
|
||||
private void applyAlignedFullFace(AoNeighborInfo neighborInfo, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) {
|
||||
AoFaceData faceData = this.getCachedFaceData(pos, dir, true);
|
||||
neighborInfo.mapCorners(faceData.lm, faceData.ao, out.lm, out.br);
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
* Calculates the light data for a grid-aligned quad that does not cover the entire block volume's face.
|
||||
* Flags: IS_ALIGNED, IS_PARTIAL
|
||||
*/
|
||||
private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) {
|
||||
private void applyAlignedPartialFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting
|
||||
float cx = clamp(quad.getX(i));
|
||||
@@ -124,13 +124,13 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPos, ForgeDirection,
|
||||
* This method is the same as {@link #applyNonParallelFace(AoNeighborInfo, ModelQuadView, BlockPosImpl, ForgeDirection,
|
||||
* QuadLightData)} but with the check for a depth of approximately 0 removed. If the quad is parallel but not
|
||||
* aligned, all of its vertices will have the same depth and this depth must be approximately greater than 0,
|
||||
* meaning the check for 0 will always return false.
|
||||
* Flags: !IS_ALIGNED, IS_PARALLEL
|
||||
*/
|
||||
private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) {
|
||||
private void applyParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting
|
||||
float cx = clamp(quad.getX(i));
|
||||
@@ -157,7 +157,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
/**
|
||||
* Flags: !IS_ALIGNED, !IS_PARALLEL
|
||||
*/
|
||||
private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPos pos, ForgeDirection dir, QuadLightData out) {
|
||||
private void applyNonParallelFace(AoNeighborInfo neighborInfo, ModelQuadView quad, BlockPosImpl pos, ForgeDirection dir, QuadLightData out) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
// Clamp the vertex positions to the block's boundaries to prevent weird errors in lighting
|
||||
float cx = clamp(quad.getX(i));
|
||||
@@ -182,7 +182,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
private void applyAlignedPartialFaceVertex(BlockPos pos, ForgeDirection dir, float[] w, int i, QuadLightData out, boolean offset) {
|
||||
private void applyAlignedPartialFaceVertex(BlockPosImpl pos, ForgeDirection dir, float[] w, int i, QuadLightData out, boolean offset) {
|
||||
AoFaceData faceData = this.getCachedFaceData(pos, dir, offset);
|
||||
|
||||
if (!faceData.hasUnpackedLightData()) {
|
||||
@@ -197,7 +197,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
out.lm[i] = getLightMapCoord(sl, bl);
|
||||
}
|
||||
|
||||
private void applyInsetPartialFaceVertex(BlockPos pos, ForgeDirection dir, float n1d, float n2d, float[] w, int i, QuadLightData out) {
|
||||
private void applyInsetPartialFaceVertex(BlockPosImpl pos, ForgeDirection dir, float n1d, float n2d, float[] w, int i, QuadLightData out) {
|
||||
AoFaceData n1 = this.getCachedFaceData(pos, dir, false);
|
||||
|
||||
if (!n1.hasUnpackedLightData()) {
|
||||
@@ -235,7 +235,7 @@ public class SmoothLightPipeline implements LightPipeline {
|
||||
/**
|
||||
* Returns the cached data for a given facing or calculates it if it hasn't been cached.
|
||||
*/
|
||||
private AoFaceData getCachedFaceData(BlockPos pos, ForgeDirection face, boolean offset) {
|
||||
private AoFaceData getCachedFaceData(BlockPosImpl pos, ForgeDirection face, boolean offset) {
|
||||
AoFaceData data = this.cachedFaceData[offset ? face.ordinal() : face.ordinal() + 6];
|
||||
|
||||
if (!data.hasLightData()) {
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
package me.jellysquid.mods.sodium.client.model.quad;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import lombok.Getter;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFlags;
|
||||
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Roughly equivalent to 16.5's BakedQuadView and BakedQuadMixin
|
||||
*/
|
||||
public class Quad implements QuadView {
|
||||
// Adapted from Neodymium
|
||||
|
||||
public static final int INTS_PER_VERTEX = 8;
|
||||
public static final int QUAD_STRIDE = INTS_PER_VERTEX * 4;
|
||||
public static final int X_INDEX = 0;
|
||||
public static final int Y_INDEX = 1;
|
||||
public static final int Z_INDEX = 2;
|
||||
public static final int U_INDEX = 3;
|
||||
public static final int V_INDEX = 4;
|
||||
public static final int COLOR_INDEX = 5;
|
||||
public static final int NORMAL_INDEX = 6;
|
||||
public static final int LIGHTMAP_INDEX = 7;
|
||||
|
||||
private final static int DEFAULT_LIGHTMAP = 15 << 20 | 15 << 4;
|
||||
private final static int DEFAULT_COLOR = 0xFFFFFFFF;
|
||||
|
||||
private final int[] data = new int[QUAD_STRIDE];
|
||||
|
||||
@Getter
|
||||
private boolean deleted;
|
||||
|
||||
private final Vector3f vectorA = new Vector3f(), vectorB = new Vector3f(), vectorC = new Vector3f();
|
||||
|
||||
@Getter
|
||||
private boolean shade;
|
||||
private int cachedFlags;
|
||||
@Getter
|
||||
private ForgeDirection face;
|
||||
private int colorIndex = -1;
|
||||
private TextureAtlasSprite sprite = null;
|
||||
|
||||
/** Returns the face, forced to take one of 6 directions to mirror the behavior of baked quads in 1.16.5. */
|
||||
@Override
|
||||
public ForgeDirection getLightFace() {
|
||||
return this.face != ForgeDirection.UNKNOWN ? this.face : ForgeDirection.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX(int idx) {
|
||||
return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + X_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getY(int idx) {
|
||||
return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + Y_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getZ(int idx) {
|
||||
return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + Z_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexU(int idx) {
|
||||
return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + U_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTexV(int idx) {
|
||||
return Float.intBitsToFloat(this.data[idx * INTS_PER_VERTEX + V_INDEX]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(int idx) {
|
||||
return this.data[idx * INTS_PER_VERTEX + COLOR_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int idx) {
|
||||
return this.data[idx * INTS_PER_VERTEX + LIGHTMAP_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNormal(int idx) {
|
||||
return this.data[idx * INTS_PER_VERTEX + NORMAL_INDEX];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlags() {
|
||||
return this.cachedFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColorIndex() {
|
||||
return this.colorIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite rubidium$getSprite() {
|
||||
return this.sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setX(int idx, float x) {
|
||||
this.data[idx * INTS_PER_VERTEX + X_INDEX] = Float.floatToRawIntBits(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setY(int idx, float y) {
|
||||
this.data[idx * INTS_PER_VERTEX + Y_INDEX] = Float.floatToRawIntBits(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZ(int idx, float z) {
|
||||
this.data[idx * INTS_PER_VERTEX + Z_INDEX] = Float.floatToRawIntBits(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexU(int idx, float u) {
|
||||
this.data[idx * INTS_PER_VERTEX + U_INDEX] = Float.floatToRawIntBits(u);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTexV(int idx, float v) {
|
||||
this.data[idx * INTS_PER_VERTEX + V_INDEX] = Float.floatToRawIntBits(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(int idx, int c) {
|
||||
this.data[idx * INTS_PER_VERTEX + COLOR_INDEX] = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLight(int idx, int l) {
|
||||
this.data[idx * INTS_PER_VERTEX + LIGHTMAP_INDEX] = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNormal(int idx, int n) {
|
||||
this.data[idx * INTS_PER_VERTEX + NORMAL_INDEX] = n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlags(int flags) {
|
||||
this.cachedFlags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorIndex(int i) {
|
||||
this.colorIndex = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSprite(TextureAtlasSprite sprite) {
|
||||
this.sprite = sprite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getRawVertexes() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: access x, y, z by index 0-2.
|
||||
*/
|
||||
private float posByIndex(int vertexIndex, int coordinateIndex) {
|
||||
return Float.intBitsToFloat(this.data[vertexIndex * INTS_PER_VERTEX + coordinateIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience: access x, y, z by index 0-2.
|
||||
*/
|
||||
private void setPosByIndex(int vertexIndex, int coordinateIndex, float val) {
|
||||
this.data[vertexIndex * INTS_PER_VERTEX + coordinateIndex] = Float.floatToRawIntBits(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset all xs, ys, or zs by index 0-2.
|
||||
*/
|
||||
private void offsetPos(int idx, float offset) {
|
||||
this.setPosByIndex(0, idx, this.posByIndex(0, idx) + offset);
|
||||
this.setPosByIndex(1, idx, this.posByIndex(1, idx) + offset);
|
||||
this.setPosByIndex(2, idx, this.posByIndex(2, idx) + offset);
|
||||
this.setPosByIndex(3, idx, this.posByIndex(3, idx) + offset);
|
||||
}
|
||||
|
||||
private void clearColors() {
|
||||
this.setColor(0, DEFAULT_COLOR);
|
||||
this.setColor(1, DEFAULT_COLOR);
|
||||
this.setColor(2, DEFAULT_COLOR);
|
||||
this.setColor(3, DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
private void clearNormals() {
|
||||
this.setNormal(0, 0);
|
||||
this.setNormal(1, 0);
|
||||
this.setNormal(2, 0);
|
||||
this.setNormal(3, 0);
|
||||
}
|
||||
|
||||
private void clearLight() {
|
||||
this.setLight(0, DEFAULT_LIGHTMAP);
|
||||
this.setLight(1, DEFAULT_LIGHTMAP);
|
||||
this.setLight(2, DEFAULT_LIGHTMAP);
|
||||
this.setLight(3, DEFAULT_LIGHTMAP);
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
return this.getX(0) == this.getX(1)
|
||||
&& this.getX(1) == this.getX(2)
|
||||
&& this.getX(2) == this.getX(3)
|
||||
&& this.getY(0) == this.getY(1)
|
||||
&& this.getY(1) == this.getY(2)
|
||||
&& this.getY(2) == this.getY(3);
|
||||
}
|
||||
|
||||
private void calcNormal() {
|
||||
this.vectorA.set(
|
||||
this.getX(1) - this.getX(0),
|
||||
this.getY(1) - this.getY(0),
|
||||
this.getZ(1) - this.getZ(0)
|
||||
);
|
||||
this.vectorB.set(
|
||||
this.getX(2) - this.getX(1),
|
||||
this.getY(2) - this.getY(1),
|
||||
this.getZ(2) - this.getZ(1)
|
||||
);
|
||||
this.vectorA.cross(this.vectorB, this.vectorC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(QuadView quad) {
|
||||
|
||||
System.arraycopy(quad.getRawVertexes(), 0, this.data, 0, QUAD_STRIDE);
|
||||
|
||||
this.deleted = quad.isDeleted();
|
||||
this.shade = quad.isShade();
|
||||
this.face = quad.getFace();
|
||||
this.colorIndex = quad.getColorIndex();
|
||||
this.cachedFlags = quad.getFlags();
|
||||
this.sprite = quad.rubidium$getSprite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike setState, setRaw assumes your quad is valid and does not compute normals, clear color/normal/lightmap
|
||||
* values, or quadrangulate. Basically the same as copyFrom but without an input quad.
|
||||
*/
|
||||
public void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags) {
|
||||
|
||||
System.arraycopy(data, 0, this.data, 0, QUAD_STRIDE);
|
||||
|
||||
this.deleted = false;
|
||||
this.shade = shade;
|
||||
this.face = face;
|
||||
this.colorIndex = colorIndex;
|
||||
this.cachedFlags = flags;
|
||||
}
|
||||
|
||||
private void read(int[] rawBuffer, int offset, float offsetX, float offsetY, float offsetZ, int drawMode, BlockRenderer.Flags flags) {
|
||||
System.arraycopy(rawBuffer, offset, this.data, 0, QUAD_STRIDE);
|
||||
|
||||
if (offsetX != 0) this.offsetPos(0, offsetX);
|
||||
if (offsetY != 0) this.offsetPos(1, offsetY);
|
||||
if (offsetZ != 0) this.offsetPos(2, offsetZ);
|
||||
|
||||
if (!flags.hasColor) this.clearColors();
|
||||
if (!flags.hasNormals) this.clearNormals();
|
||||
if (!flags.hasBrightness) this.clearLight();
|
||||
|
||||
// sus
|
||||
this.shade = flags.hasBrightness;
|
||||
|
||||
if (drawMode == GL11.GL_TRIANGLES) {
|
||||
|
||||
// Quadrangulate!
|
||||
this.setX(3, this.getX(2));
|
||||
this.setY(3, this.getY(2));
|
||||
this.setZ(3, this.getZ(2));
|
||||
|
||||
this.setTexU(3, this.getTexU(2));
|
||||
this.setTexV(3, this.getTexV(2));
|
||||
|
||||
this.setLight(3, this.getLight(2));
|
||||
this.setColor(3, this.getColor(2));
|
||||
this.setNormal(3, this.getNormal(2));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ) {
|
||||
this.deleted = false;
|
||||
|
||||
read(rawBuffer, offset, offsetX, offsetY, offsetZ, drawMode, flags);
|
||||
|
||||
if (this.isEmpty()) {
|
||||
// ignore empty quads (e.g. alpha pass of EnderIO item conduits)
|
||||
this.deleted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this.calcNormal();
|
||||
this.face = ModelQuadFacing.toDirection(ModelQuadFacing.fromVector(this.vectorC));
|
||||
this.cachedFlags = ModelQuadFlags.getQuadFlags(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
Locale.ENGLISH,
|
||||
"%s[(%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f), (%.1f, %.1f, %.1f)]",
|
||||
this.deleted ? "XXX " : "",
|
||||
this.getX(0),
|
||||
this.getY(0),
|
||||
this.getZ(0),
|
||||
this.getX(1),
|
||||
this.getY(1),
|
||||
this.getZ(1),
|
||||
this.getX(2),
|
||||
this.getY(2),
|
||||
this.getZ(2),
|
||||
this.getX(3),
|
||||
this.getY(3),
|
||||
this.getZ(3)
|
||||
);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.chunk;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos;
|
||||
import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils;
|
||||
import lombok.Getter;
|
||||
@@ -265,8 +265,8 @@ public class ChunkRenderContainer<T extends ChunkGraphicsState> {
|
||||
return this.getOriginZ() + 8.0D;
|
||||
}
|
||||
|
||||
public BlockPos getRenderOrigin() {
|
||||
return new BlockPos(this.getRenderX(), this.getRenderY(), this.getRenderZ());
|
||||
public BlockPosImpl getRenderOrigin() {
|
||||
return new BlockPosImpl(this.getRenderX(), this.getRenderY(), this.getRenderZ());
|
||||
}
|
||||
|
||||
public void setGraphicsState(BlockRenderPass pass, T state) {
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.chunk.cull.graph;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.Camera;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionData;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos;
|
||||
@@ -77,7 +77,7 @@ public class ChunkGraphCuller implements ChunkCuller {
|
||||
|
||||
this.visible.clear();
|
||||
|
||||
BlockPos origin = camera.getBlockPos();
|
||||
BlockPosImpl origin = camera.getBlockPos();
|
||||
|
||||
int chunkX = origin.getX() >> 4;
|
||||
int chunkY = origin.getY() >> 4;
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.chunk.cull.graph;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionData;
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderData;
|
||||
import me.jellysquid.mods.sodium.client.util.math.FrustumExtended;
|
||||
@@ -146,7 +146,7 @@ public class ChunkGraphNode {
|
||||
* @return The squared distance from the center of this chunk in the world to the center of the block position
|
||||
* given by {@param pos}
|
||||
*/
|
||||
public double getSquaredDistance(BlockPos pos) {
|
||||
public double getSquaredDistance(BlockPosImpl pos) {
|
||||
return this.getSquaredDistance(pos.x + 0.5D, pos.y + 0.5D, pos.z + 0.5D);
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.chunk.tasks;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkOcclusionDataBuilder;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
|
||||
@@ -48,7 +48,7 @@ import java.util.concurrent.ExecutionException;
|
||||
public class ChunkRenderRebuildTask<T extends ChunkGraphicsState> extends ChunkRenderBuildTask<T> {
|
||||
private final ChunkRenderContainer<T> render;
|
||||
|
||||
private final BlockPos offset;
|
||||
private final BlockPosImpl offset;
|
||||
|
||||
private final ChunkRenderContext context;
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ChunkRenderRebuildTask<T extends ChunkGraphicsState> extends ChunkR
|
||||
|
||||
private final boolean translucencySorting;
|
||||
|
||||
public ChunkRenderRebuildTask(ChunkRenderContainer<T> render, ChunkRenderContext context, BlockPos offset) {
|
||||
public ChunkRenderRebuildTask(ChunkRenderContainer<T> render, ChunkRenderContext context, BlockPosImpl offset) {
|
||||
this.render = render;
|
||||
this.offset = offset;
|
||||
this.context = context;
|
||||
@@ -121,8 +121,8 @@ public class ChunkRenderRebuildTask<T extends ChunkGraphicsState> extends ChunkR
|
||||
final int baseY = this.render.getOriginY();
|
||||
final int baseZ = this.render.getOriginZ();
|
||||
|
||||
final BlockPos pos = new BlockPos();
|
||||
final BlockPos renderOffset = this.offset;
|
||||
final BlockPosImpl pos = new BlockPosImpl();
|
||||
final BlockPosImpl renderOffset = this.offset;
|
||||
|
||||
final LongArrayFIFOQueue mainThreadBlocks = new LongArrayFIFOQueue();
|
||||
boolean hasMainThreadBlocks = false;
|
||||
@@ -240,11 +240,11 @@ public class ChunkRenderRebuildTask<T extends ChunkGraphicsState> extends ChunkR
|
||||
*/
|
||||
private void performMainBuild(ChunkRenderCacheLocal cache, ChunkBuildBuffers buffers, CancellationSource cancellationSource, ChunkRenderBounds.Builder bounds, ChunkRenderData.Builder renderData, LongArrayFIFOQueue mainThreadBlocks) {
|
||||
final WorldSlice slice = cache.getWorldSlice();
|
||||
final BlockPos pos = new BlockPos();
|
||||
final BlockPosImpl pos = new BlockPosImpl();
|
||||
final int baseX = this.render.getOriginX();
|
||||
final int baseY = this.render.getOriginY();
|
||||
final int baseZ = this.render.getOriginZ();
|
||||
final BlockPos renderOffset = this.offset;
|
||||
final BlockPosImpl renderOffset = this.offset;
|
||||
final RenderBlocks rb = new RenderBlocks(slice.getWorld());
|
||||
while(!mainThreadBlocks.isEmpty()) {
|
||||
final long longPos = mainThreadBlocks.dequeueLong();
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.chunk.tasks;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import me.jellysquid.mods.sodium.client.gl.buffer.VertexData;
|
||||
import me.jellysquid.mods.sodium.client.gl.util.BufferSlice;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
|
||||
@@ -32,10 +32,10 @@ public class ChunkRenderTranslucencySortTask<T extends ChunkGraphicsState> exten
|
||||
private static final BlockRenderPass[] NO_PASSES = new BlockRenderPass[0];
|
||||
|
||||
private final ChunkRenderContainer<T> render;
|
||||
private final BlockPos offset;
|
||||
private final BlockPosImpl offset;
|
||||
private final Vector3d camera;
|
||||
|
||||
public ChunkRenderTranslucencySortTask(ChunkRenderContainer<T> render, BlockPos offset, Vector3d camera) {
|
||||
public ChunkRenderTranslucencySortTask(ChunkRenderContainer<T> render, BlockPosImpl offset, Vector3d camera) {
|
||||
this.render = render;
|
||||
this.offset = offset;
|
||||
this.camera = camera;
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
package me.jellysquid.mods.sodium.client.render.entity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
|
||||
public interface EntityLightSampler<T extends Entity> {
|
||||
int bridge$getBlockLight(T entity, BlockPos pos);
|
||||
int bridge$getBlockLight(T entity, BlockPosImpl pos);
|
||||
|
||||
int bridge$getSkyLight(T entity, BlockPos pos);
|
||||
int bridge$getSkyLight(T entity, BlockPosImpl pos);
|
||||
}
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.occlusion;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
@@ -11,7 +11,7 @@ public class BlockOcclusionCache {
|
||||
|
||||
private final Object2ByteLinkedOpenHashMap<CachedOcclusionShapeTest> map;
|
||||
private final CachedOcclusionShapeTest cachedTest = new CachedOcclusionShapeTest();
|
||||
private final BlockPos cpos = new BlockPos();
|
||||
private final BlockPosImpl cpos = new BlockPosImpl();
|
||||
|
||||
public BlockOcclusionCache() {
|
||||
this.map = new Object2ByteLinkedOpenHashMap<>(2048, 0.5F);
|
||||
@@ -26,11 +26,11 @@ public class BlockOcclusionCache {
|
||||
* @param facing The facing direction of the side to check
|
||||
* @return True if the block side facing {@param dir} is not occluded, otherwise false
|
||||
*/
|
||||
public boolean shouldDrawSide(Block block, int meta, IBlockAccess view, BlockPos pos, ForgeDirection facing) {
|
||||
public boolean shouldDrawSide(Block block, int meta, IBlockAccess view, BlockPosImpl pos, ForgeDirection facing) {
|
||||
if (facing == ForgeDirection.UNKNOWN)
|
||||
return true;
|
||||
|
||||
BlockPos adjPos = this.cpos;
|
||||
BlockPosImpl adjPos = this.cpos;
|
||||
adjPos.set(pos.getX() + facing.offsetX, pos.getY() + facing.offsetY, pos.getZ() + facing.offsetZ);
|
||||
|
||||
Block adjState = view.getBlock(adjPos.x, adjPos.y, adjPos.z);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package me.jellysquid.mods.sodium.client.render.pipeline;
|
||||
|
||||
import com.gtnewhorizons.angelica.api.QuadProvider;
|
||||
import com.gtnewhorizons.angelica.api.QuadView;
|
||||
import com.gtnewhorizons.angelica.client.renderer.CapturingTessellator;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.nd.Quad;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import me.jellysquid.mods.sodium.client.model.quad.Quad;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import com.gtnewhorizons.angelica.glsm.TessellatorManager;
|
||||
import com.gtnewhorizons.angelica.utils.ObjectPooler;
|
||||
@@ -43,7 +44,7 @@ public class BlockRenderer {
|
||||
private final LightPipelineProvider lighters;
|
||||
private final BlockOcclusionCache occlusionCache;
|
||||
|
||||
private final ObjectPooler<Quad> quadPool = new ObjectPooler<>(Quad::new);
|
||||
private final ObjectPooler<QuadView> quadPool = new ObjectPooler<>(Quad::new);
|
||||
// TODO: Use modern model API, and store them here
|
||||
|
||||
|
||||
@@ -54,7 +55,7 @@ public class BlockRenderer {
|
||||
this.occlusionCache = new BlockOcclusionCache();
|
||||
}
|
||||
|
||||
public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block block, int meta, BlockPos pos, ChunkModelBuffers buffers, boolean cull, long seed) {
|
||||
public boolean renderModel(IBlockAccess world, RenderBlocks renderBlocks, Block block, int meta, BlockPosImpl pos, ChunkModelBuffers buffers, boolean cull, long seed) {
|
||||
final LightMode mode = this.getLightingMode(block);
|
||||
final LightPipeline lighter = this.lighters.getLighter(mode);
|
||||
|
||||
@@ -69,18 +70,18 @@ public class BlockRenderer {
|
||||
for (ForgeDirection dir : ForgeDirection.values()) {
|
||||
|
||||
this.random.setSeed(seed);
|
||||
List<Quad> quads = null;
|
||||
List<QuadView> quads;
|
||||
|
||||
if (!cull || this.occlusionCache.shouldDrawSide(block, meta, world, pos, dir)) {
|
||||
quads = qBlock.getQuads(world, pos, block, meta, dir, random, color, this.quadPool);
|
||||
quads = qBlock.getQuads(world, pos, block, meta, dir, random, color, this.quadPool::getInstance);
|
||||
if (quads.isEmpty()) continue;
|
||||
|
||||
this.renderQuadList(pos, lighter, buffers, quads, ModelQuadFacing.fromDirection(dir), true);
|
||||
rendered = true;
|
||||
}
|
||||
|
||||
if (quads != null)
|
||||
for (Quad q : quads) this.quadPool.releaseInstance(q);
|
||||
if (qBlock.isDynamic())
|
||||
for (QuadView q : quads) this.quadPool.releaseInstance(q);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -92,7 +93,7 @@ public class BlockRenderer {
|
||||
|
||||
tess.setOffset(pos);
|
||||
renderBlocks.renderBlockByRenderType(block, pos.x, pos.y, pos.z);
|
||||
final List<Quad> quads = TessellatorManager.stopCapturingToPooledQuads();
|
||||
final List<QuadView> quads = TessellatorManager.stopCapturingToPooledQuads();
|
||||
tess.resetOffset();
|
||||
|
||||
for (ModelQuadFacing facing : ModelQuadFacing.VALUES) {
|
||||
@@ -109,7 +110,7 @@ public class BlockRenderer {
|
||||
return rendered;
|
||||
}
|
||||
|
||||
private void renderQuadList(BlockPos pos, LightPipeline lighter, ChunkModelBuffers buffers, List<Quad> quads, ModelQuadFacing facing, boolean useSodiumLight) {
|
||||
private void renderQuadList(BlockPosImpl pos, LightPipeline lighter, ChunkModelBuffers buffers, List<QuadView> quads, ModelQuadFacing facing, boolean useSodiumLight) {
|
||||
final ForgeDirection cullFace = ModelQuadFacing.toDirection(facing);
|
||||
|
||||
final ModelVertexSink sink = buffers.getSink(facing);
|
||||
@@ -120,7 +121,7 @@ public class BlockRenderer {
|
||||
// This is a very hot allocation, iterate over it manually
|
||||
// noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, quadsSize = quads.size(); i < quadsSize; i++) {
|
||||
final Quad quad = quads.get(i);
|
||||
final QuadView quad = quads.get(i);
|
||||
|
||||
// If we aren't using sodium light (i.e. it's the CapturingTesselator)
|
||||
// manually filter quads by side
|
||||
@@ -138,7 +139,7 @@ public class BlockRenderer {
|
||||
sink.flush();
|
||||
}
|
||||
|
||||
private void renderQuad(ModelVertexSink sink, Quad quad, QuadLightData light, ChunkRenderData.Builder renderData, boolean useSodiumLight) {
|
||||
private void renderQuad(ModelVertexSink sink, QuadView quad, QuadLightData light, ChunkRenderData.Builder renderData, boolean useSodiumLight) {
|
||||
|
||||
final ModelQuadOrientation order = (useSodiumLight || this.useSeparateAo) ? ModelQuadOrientation.orient(light.br) : ModelQuadOrientation.NORMAL;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.client.render.pipeline;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import com.gtnewhorizons.angelica.config.AngelicaConfig;
|
||||
import me.jellysquid.mods.sodium.client.model.light.LightMode;
|
||||
import me.jellysquid.mods.sodium.client.model.light.LightPipeline;
|
||||
@@ -38,7 +38,7 @@ public class FluidRenderer {
|
||||
private static final float EPSILON = 0.001f;
|
||||
private final LightPipelineProvider lpp;
|
||||
|
||||
private final BlockPos.Mutable scratchPos = new BlockPos.Mutable();
|
||||
private final BlockPosImpl scratchPos = new BlockPosImpl();
|
||||
|
||||
private final ModelQuadViewMutable quad = new ModelQuad();
|
||||
|
||||
@@ -69,7 +69,7 @@ public class FluidRenderer {
|
||||
}
|
||||
|
||||
private boolean isSideExposed(IBlockAccess world, int x, int y, int z, ForgeDirection dir, float height) {
|
||||
BlockPos pos = this.scratchPos.set(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ);
|
||||
BlockPosImpl pos = this.scratchPos.set(x + dir.offsetX, y + dir.offsetY, z + dir.offsetZ);
|
||||
Block block = world.getBlock(pos.x, pos.y, pos.z);
|
||||
|
||||
if (block.getMaterial().isOpaque()) {
|
||||
@@ -87,7 +87,7 @@ public class FluidRenderer {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean render(IBlockAccess world, WorldSlice slice, Block block, BlockPos pos, ChunkModelBuffers buffers) {
|
||||
public boolean render(IBlockAccess world, WorldSlice slice, Block block, BlockPosImpl pos, ChunkModelBuffers buffers) {
|
||||
this.useSeparateAo = AngelicaConfig.enableIris && BlockRenderingSettings.INSTANCE.shouldUseSeparateAo();
|
||||
|
||||
int posX = pos.x;
|
||||
@@ -349,7 +349,7 @@ public class FluidRenderer {
|
||||
return rendered;
|
||||
}
|
||||
|
||||
private void calculateQuadColors(ModelQuadView quad, BlockPos pos, LightPipeline lighter, ForgeDirection dir, float brightness, boolean colorized, WorldSlice slice) {
|
||||
private void calculateQuadColors(ModelQuadView quad, BlockPosImpl pos, LightPipeline lighter, ForgeDirection dir, float brightness, boolean colorized, WorldSlice slice) {
|
||||
QuadLightData light = this.quadLightData;
|
||||
lighter.calculate(quad, pos, light, null, dir, false);
|
||||
|
||||
@@ -437,7 +437,7 @@ public class FluidRenderer {
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
BlockPos pos = this.scratchPos.set(x2, y, z2);
|
||||
BlockPosImpl pos = this.scratchPos.set(x2, y, z2);
|
||||
|
||||
block = world.getBlock(pos.x, pos.y, pos.z);
|
||||
int meta = world.getBlockMetadata(pos.x, pos.y, pos.z);
|
||||
|
||||
@@ -3,7 +3,6 @@ package me.jellysquid.mods.sodium.client.world.cloned;
|
||||
import com.falsepattern.endlessids.mixin.helpers.ChunkBiomeHook;
|
||||
import com.gtnewhorizons.angelica.compat.ExtendedBlockStorageExt;
|
||||
import com.gtnewhorizons.angelica.compat.ModStatus;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.ChunkSectionPos;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package me.jellysquid.mods.sodium.common.util;
|
||||
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPos;
|
||||
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.material.Material;
|
||||
@@ -70,7 +70,7 @@ public class WorldUtil {
|
||||
* Returns true if any block in a 3x3x3 cube is not the same fluid and not an opaque full cube.
|
||||
* Equivalent to FluidState::method_15756 in modern.
|
||||
*/
|
||||
public static boolean method_15756(IBlockAccess world, BlockPos pos, Fluid fluid) {
|
||||
public static boolean method_15756(IBlockAccess world, BlockPosImpl pos, Fluid fluid) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
Block block = world.getBlock(pos.x, pos.y, pos.z);
|
||||
@@ -126,7 +126,7 @@ public class WorldUtil {
|
||||
/**
|
||||
* Equivalent to method_15749 in 1.16.5
|
||||
*/
|
||||
public static boolean method_15749(IBlockAccess world, Fluid thiz, BlockPos pos, ForgeDirection dir) {
|
||||
public static boolean method_15749(IBlockAccess world, Fluid thiz, BlockPosImpl pos, ForgeDirection dir) {
|
||||
Block b = world.getBlock(pos.x, pos.y, pos.z);
|
||||
Fluid f = getFluid(b);
|
||||
if (f == thiz) {
|
||||
|
||||
Reference in new issue
Block a user