From efc6a8ecd05b61dfc20448d660e201f03de1ab4c Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Fri, 19 Nov 2021 21:26:04 +0300 Subject: [PATCH] Hastily added pine trees and hazel bushes - Added ShapePrototype wrapper for ShapePart batch creation - Added pine trees and hazel bushes - Leaves with custom block models - Improved tree generator --- .../client/graphics/model/ShapeParts.java | 2 +- .../client/graphics/model/ShapePrototype.java | 248 ++++++++++++++++++ .../windcorp/progressia/test/TestContent.java | 9 +- .../test/gen/feature/TestBushFeature.java | 8 +- .../test/gen/feature/TestTreeFeature.java | 41 +-- .../test/trees/BlockRenderLeavesHazel.java | 99 +++++++ .../test/trees/BlockRenderLeavesPine.java | 106 ++++++++ .../assets/textures/blocks/LeavesHazel.png | Bin 0 -> 408 bytes .../assets/textures/blocks/LeavesPine.png | Bin 0 -> 6521 bytes .../assets/textures/blocks/LogSide.png | Bin 7213 -> 6976 bytes .../assets/textures/blocks/LogTop.png | Bin 8247 -> 6645 bytes 11 files changed, 493 insertions(+), 20 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePrototype.java create mode 100644 src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesHazel.java create mode 100644 src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesPine.java create mode 100644 src/main/resources/assets/textures/blocks/LeavesHazel.png create mode 100644 src/main/resources/assets/textures/blocks/LeavesPine.png diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java index 4030249..807fcda 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapeParts.java @@ -153,6 +153,6 @@ public class ShapeParts { height, inner ); - } + } } diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePrototype.java b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePrototype.java new file mode 100644 index 0000000..f2cc631 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/graphics/model/ShapePrototype.java @@ -0,0 +1,248 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.client.graphics.model; + +import java.nio.ShortBuffer; +import java.util.Objects; + +import glm.mat._3.Mat3; +import glm.mat._4.Mat4; +import glm.vec._2.Vec2; +import glm.vec._3.Vec3; +import glm.vec._4.Vec4; +import ru.windcorp.progressia.client.graphics.Colors; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram.VertexBuilder; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram.WRPVertexBuilder; +import ru.windcorp.progressia.common.util.StashingStack; +import ru.windcorp.progressia.common.util.VectorUtil; + +public class ShapePrototype { + + private final ShapeRenderProgram program; + + private Texture texture; + + private final Vec3[] positions; + private final Vec4[] colorMultipliers; + private final Vec2[] textureCoords; + private final Vec3[] forcedNormals; + + private ShortBuffer indices; + private ShortBuffer flippedIndices = null; + + protected static final int TRANSFORM_STACK_SIZE = 64; + private final StashingStack transformStack = new StashingStack<>( + TRANSFORM_STACK_SIZE, + Mat4::new + ); + + public ShapePrototype( + ShapeRenderProgram program, + Texture texture, + Vec3[] positions, + Vec4[] colorMultipliers, + Vec2[] textureCoords, + Vec3[] forcedNormals, + ShortBuffer indices + ) { + this.program = Objects.requireNonNull(program, "program"); + this.texture = texture; + this.indices = Objects.requireNonNull(indices, "indices"); + + Objects.requireNonNull(positions, "positions"); + Objects.requireNonNull(colorMultipliers, "colorMultipliers"); + Objects.requireNonNull(textureCoords, "textureCoords"); + + if (forcedNormals != null && !(program instanceof WorldRenderProgram)) { + throw new IllegalArgumentException("Cannot force normals on non-WorldRenderPrograms cuz javahorse stupiddd"); + } + + if (forcedNormals == null) { + forcedNormals = new Vec3[positions.length]; + } + + this.positions = positions; + this.colorMultipliers = colorMultipliers; + this.textureCoords = textureCoords; + this.forcedNormals = forcedNormals; + + if (positions.length != colorMultipliers.length) { + throw new IllegalArgumentException("positions.length (" + positions.length + ") != colorMultipliers.length (" + colorMultipliers + ")"); + } + + if (positions.length != textureCoords.length) { + throw new IllegalArgumentException("positions.length (" + positions.length + ") != textureCoords.length (" + textureCoords + ")"); + } + + if (positions.length != forcedNormals.length) { + throw new IllegalArgumentException("positions.length (" + positions.length + ") != forcedNormals.length (" + forcedNormals + ")"); + } + + transformStack.push().identity(); + } + + public ShapePart build() { + VertexBuilder builder = program.getVertexBuilder(); + + Vec3 transformedPosition = new Vec3(); + + for (int i = 0; i < positions.length; ++i) { + + transformedPosition.set(positions[i]); + if (transformStack.getSize() > 1) { + VectorUtil.applyMat4(transformedPosition, transformStack.getHead()); + } + + if (forcedNormals[i] != null && builder instanceof WRPVertexBuilder) { + ((WRPVertexBuilder) builder).addVertex( + transformedPosition, colorMultipliers[i], textureCoords[i], forcedNormals[i] + ); + } else { + builder.addVertex(transformedPosition, colorMultipliers[i], textureCoords[i]); + } + } + + return new ShapePart(texture, builder.assemble(), indices); + } + + public ShapePrototype apply(Mat4 transform) { + for (Vec3 vector : positions) { + VectorUtil.applyMat4(vector, transform); + } + return this; + } + + public ShapePrototype apply(Mat3 transform) { + for (Vec3 vector : positions) { + transform.mul(vector); + } + return this; + } + + public Mat4 push() { + Mat4 previous = transformStack.getHead(); + return transformStack.push().set(previous); + } + + public ShapePrototype pop() { + transformStack.pop(); + return this; + } + + public ShapePrototype setTexture(Texture texture) { + this.texture = texture; + return this; + } + + public ShapePrototype deleteTexture() { + this.texture = null; + return this; + } + + public ShapePrototype resetColorMultiplier() { + for (Vec4 color : colorMultipliers) { + color.set(Colors.WHITE); + } + return this; + } + + public ShapePrototype addColorMultiplier(Vec4 color) { + for (Vec4 c : colorMultipliers) { + c.mul(color); + } + return this; + } + + public ShapePrototype flip() { + ShortBuffer tmp = indices; + indices = flippedIndices; + flippedIndices = tmp; + + if (indices == null) { + int length = flippedIndices.limit(); + indices = ShortBuffer.allocate(length); + for (int i = 0; i < length; ++i) { + indices.put(i, flippedIndices.get(length - i - 1)); + } + } + + return this; + } + + public ShapePrototype makeDoubleSided() { + int length = indices.limit(); + ShortBuffer newIndices = ShortBuffer.allocate(length * 2); + + for (int i = 0; i < length; ++i) { + newIndices.put(i, indices.get(i)); + } + for (int i = 0; i < length; ++i) { + newIndices.put(i + length, indices.get(length - i - 1)); + } + + indices = flippedIndices = newIndices; + + return this; + } + + public static ShapePrototype unitSquare(Texture texture, Vec4 color, ShapeRenderProgram program) { + return new ShapePrototype( + program, + texture, + new Vec3[] { + new Vec3(0, 0, 0), + new Vec3(0, 1, 0), + new Vec3(1, 0, 0), + new Vec3(1, 1, 0) + }, + new Vec4[] { + new Vec4(color), + new Vec4(color), + new Vec4(color), + new Vec4(color) + }, + new Vec2[] { + new Vec2(0, 0), + new Vec2(0, 1), + new Vec2(1, 0), + new Vec2(1, 1) + }, + null, + ShortBuffer.wrap(new short[] {3, 1, 0, 2, 3, 0}) + ); + } + + public static ShapePrototype unitSquare(Texture texture, Vec4 color) { + return unitSquare(texture, color, WorldRenderProgram.getDefault()); + } + + public static ShapePrototype unitSquare(Texture texture) { + return unitSquare(texture, Colors.WHITE, WorldRenderProgram.getDefault()); + } + + public static ShapePrototype unitSquare(Vec4 color) { + return unitSquare(null, color, WorldRenderProgram.getDefault()); + } + + public static ShapePrototype unitSquare() { + return unitSquare(null, Colors.WHITE, WorldRenderProgram.getDefault()); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index e027cef..c2444d2 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -65,6 +65,8 @@ import ru.windcorp.progressia.server.world.tile.*; import ru.windcorp.progressia.test.Flowers.FlowerVariant; import ru.windcorp.progressia.test.Rocks.RockType; import ru.windcorp.progressia.test.gen.TestGravityModel; +import ru.windcorp.progressia.test.trees.BlockRenderLeavesHazel; +import ru.windcorp.progressia.test.trees.BlockRenderLeavesPine; public class TestContent { @@ -131,7 +133,7 @@ public class TestContent { register(new BlockLogic("Test:Log")); register(new BlockData("Test:TemporaryLeaves")); - register(new BlockRenderTransparentCube("Test:TemporaryLeaves", getBlockTexture("TemporaryLeaves"))); + register(new BlockRenderLeavesHazel("Test:TemporaryLeaves", getBlockTexture("LeavesHazel"))); // Sic, using Glass logic for leaves because Test register(new TestBlockLogicGlass("Test:TemporaryLeaves")); @@ -142,6 +144,11 @@ public class TestContent { register(new BlockData("Test:Tux")); register(new TestBlockRenderTux("Test:Tux")); register(new BlockLogic("Test:Tux")); + + register(new BlockData("Test:LeavesPine")); + register(new BlockRenderLeavesPine("Test:LeavesPine", getBlockTexture("LeavesPine"))); + // Sic, using Glass logic for leaves because Test + register(new TestBlockLogicGlass("Test:LeavesPine")); BlockDataRegistry.getInstance().values().forEach(PLACEABLE_BLOCKS::add); PLACEABLE_BLOCKS.removeIf(b -> placeableBlacklist.contains(b.getId())); diff --git a/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java index b559582..84328bd 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestBushFeature.java @@ -38,10 +38,12 @@ public class TestBushFeature extends MultiblockVegetationFeature { Vec3i center = context.getLocation().add_(0, 0, 1); - context.setBlock(center, trunk); - context.setBlock(center.add_(0, 0, 1), leaves); + if (size > 0.8) { + context.setBlock(center, trunk); + context.setBlock(center.add_(0, 0, 1), leaves); + } - iterateBlob(center, stretch(size, 1.3, 2.5), stretch(size, 0.6, 1.5), 0.7, 2, p -> { + iterateBlob(center, stretch(size, 0.5, 2.5), stretch(size, 0.6, 1.5), 0.7, 2, p -> { setLeaves(context, p, leaves); }); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java index 611ec07..72becc1 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/feature/TestTreeFeature.java @@ -24,33 +24,44 @@ import ru.windcorp.progressia.server.world.generation.surface.SurfaceFloatField; import ru.windcorp.progressia.server.world.generation.surface.context.SurfaceBlockContext; public class TestTreeFeature extends MultiblockVegetationFeature { - + private final BlockData trunk = BlockDataRegistry.getInstance().get("Test:Log"); - private final BlockData leaves = BlockDataRegistry.getInstance().get("Test:TemporaryLeaves"); + private final BlockData leaves = BlockDataRegistry.getInstance().get("Test:LeavesPine"); public TestTreeFeature(String id, SurfaceFloatField selector) { - super(id, selector, 10 * 10); + super(id, selector, 7 * 7); } - + @Override protected void grow(SurfaceBlockContext context, double selectorValue) { - + Vec3i start = context.getLocation().add_(0, 0, 1); Vec3i center = start.add_(0); double size = selectorValue * randomDouble(context, 0.8, 1.2); - - int height = (int) stretch(size, 3, 7); + double volume = stretch(size, 2.5, 1); + + int height = (int) stretch(size, 8, 12); for (; center.z < start.z + height; ++center.z) { context.setBlock(center, trunk); } - - double branchHorDistance = 0; + --center.z; + + iterateBlob(center, 1.5 * volume, 1.75, 0.5, 3, p -> { + setLeaves(context, p, leaves); + }); + + int branchCount = 1 + context.getRandom().nextInt(2) + (int) (stretch(size, 0, 4)); + + for (int i = 0; i < branchCount; ++i) { - do { - double branchSize = 0.5 + randomDouble(context, 1, 2) * size; double branchHorAngle = randomDouble(context, 0, 2 * Math.PI); - int branchVertOffset = (int) randomDouble(context, -2, 0); + double branchHorDistance = randomDouble(context, 0.7, 1.5) * volume; + + int branchVertOffset = (int) randomDouble(context, -height / 3.0, -height / 1.5); + + double branchSize = randomDouble(context, 1, 2) * volume; + double branchHeight = 1.5; Vec3i branchCenter = center.add_( (int) (Math.sin(branchHorAngle) * branchHorDistance), @@ -58,12 +69,12 @@ public class TestTreeFeature extends MultiblockVegetationFeature { branchVertOffset ); - iterateBlob(branchCenter, 1 * branchSize, 2.3 * branchSize, 0.5, 3, p -> { + iterateBlob(branchCenter, branchSize, branchHeight, 0.5, 3, p -> { setLeaves(context, p, leaves); }); - branchHorDistance = randomDouble(context, 0.7, 1.5); - } while (context.getRandom().nextInt(8) > 1); + } + } } diff --git a/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesHazel.java b/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesHazel.java new file mode 100644 index 0000000..9626b16 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesHazel.java @@ -0,0 +1,99 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.trees; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.graphics.backend.Usage; +import ru.windcorp.progressia.client.graphics.model.Renderable; +import ru.windcorp.progressia.client.graphics.model.Shape; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapePrototype; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.block.BlockRender; +import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSimple.BlockOptimizedSimple; +import ru.windcorp.progressia.common.world.DefaultChunkData; + +public class BlockRenderLeavesHazel extends BlockRender implements BlockOptimizedSimple { + + private final Texture texture; + + public BlockRenderLeavesHazel(String id, Texture texture) { + super(id); + this.texture = texture; + } + + @Override + public void getShapeParts(DefaultChunkData chunk, Vec3i bic, Consumer output) { + ShapePrototype sp = ShapePrototype.unitSquare(texture).makeDoubleSided(); + sp.push().translate(bic.x, bic.y, bic.z); + + Random random = new Random(chunk.getX() ^ bic.x); + random.setSeed(random.nextLong() ^ chunk.getY() ^ bic.y); + random.setSeed(random.nextLong() ^ chunk.getZ() ^ bic.z); + + final float angle = (float) (Math.PI / 4); + + sp.push().translate(0, 0, random.nextFloat() * 0.5f) + .rotateZ(random.nextFloat() * Math.PI) + .rotateX(-0.3f + random.nextFloat() * 0.6) + .scale(1.3f); + + sp.push().translate(0, 0, -0.5f).rotateX(angle).translate(-0.5f, -0.5f, 0); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.5f).rotateX(-angle).translate(-0.5f, -0.5f, 0); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.5f).rotateY(angle).translate(-0.5f, -0.5f, 0); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.5f).rotateY(-angle).translate(-0.5f, -0.5f, 0); + output.accept(sp.build()); + sp.pop(); + + sp.pop(); + } + + @Override + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { + Collection parts = new ArrayList<>(6); + + getShapeParts(chunk, blockInChunk, parts::add); + + return new Shape( + Usage.STATIC, + WorldRenderProgram.getDefault(), + parts.toArray(new ShapePart[parts.size()]) + ); + } + + @Override + public boolean needsOwnRenderable() { + return false; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesPine.java b/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesPine.java new file mode 100644 index 0000000..32f98b5 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/test/trees/BlockRenderLeavesPine.java @@ -0,0 +1,106 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.test.trees; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Random; +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.client.graphics.Colors; +import ru.windcorp.progressia.client.graphics.backend.Usage; +import ru.windcorp.progressia.client.graphics.model.Renderable; +import ru.windcorp.progressia.client.graphics.model.Shape; +import ru.windcorp.progressia.client.graphics.model.ShapePart; +import ru.windcorp.progressia.client.graphics.model.ShapePrototype; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.block.BlockRender; +import ru.windcorp.progressia.client.world.cro.ChunkRenderOptimizerSimple.BlockOptimizedSimple; +import ru.windcorp.progressia.common.world.DefaultChunkData; + +public class BlockRenderLeavesPine extends BlockRender implements BlockOptimizedSimple { + + private final Texture texture; + + public BlockRenderLeavesPine(String id, Texture texture) { + super(id); + this.texture = texture; + } + + @Override + public void getShapeParts(DefaultChunkData chunk, Vec3i bic, Consumer output) { + Random random = new Random(chunk.getX() ^ bic.x); + random.setSeed(random.nextLong() ^ chunk.getY() ^ bic.y); + random.setSeed(random.nextLong() ^ chunk.getZ() ^ bic.z); + + ShapePrototype sp = ShapePrototype.unitSquare(texture).makeDoubleSided(); + sp.push().translate( + bic.x + random.nextFloat() * 0.3f - 0.15f, + bic.y + random.nextFloat() * 0.3f - 0.15f, + bic.z + ); + + final float angle = 0.5f; + + for (float offset : new float[] { -0.25f, -0.75f }) { + sp.push().translate(0, 0, offset + random.nextFloat() * 0.5f) + .rotateZ(-0.3f + random.nextFloat() * 0.6) + .rotateX(-0.3f + random.nextFloat() * 0.6); + + sp.push().translate(0, 0, -0.3f).rotateX(angle).translate(-0.5f, -0.5f, 0.5f); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.3f).rotateX(-angle).translate(-0.5f, -0.5f, 0.5f); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.3f).rotateY(angle).translate(-0.5f, -0.5f, 0.5f); + output.accept(sp.build()); + sp.pop(); + + sp.push().translate(0, 0, -0.3f).rotateY(-angle).translate(-0.5f, -0.5f, 0.5f); + output.accept(sp.build()); + sp.pop(); + + sp.pop(); + sp.addColorMultiplier(Colors.GRAY_A); + } + } + + @Override + public Renderable createRenderable(DefaultChunkData chunk, Vec3i blockInChunk) { + Collection parts = new ArrayList<>(6); + + getShapeParts(chunk, blockInChunk, parts::add); + + return new Shape( + Usage.STATIC, + WorldRenderProgram.getDefault(), + parts.toArray(new ShapePart[parts.size()]) + ); + } + + @Override + public boolean needsOwnRenderable() { + return false; + } + +} diff --git a/src/main/resources/assets/textures/blocks/LeavesHazel.png b/src/main/resources/assets/textures/blocks/LeavesHazel.png new file mode 100644 index 0000000000000000000000000000000000000000..ec12d2db91219e8965ad3cf09cd405552fb2b8f1 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;w=>VS)S3yRGxSW9GqTsBG(89Xt z^47$@X8ErH3%oqwT1C=qB1o;IsI6S+N2IO!SctjR6Fz6|RFk{71`!b*)dx@v7 zEBjM!VF79ODWM`efI^Zbt`Q~9`MJ5Nc_j?aMX8A;sVNHOnI#zt?w-B@;f;LaKt=aF zT^vIsF6&O%?RVHgz_tJS?*hpmOp~85`z%`0mm+;@s{9gJ#fJgAiZp^1e&nVF=9!k4 zq&>@W`08~!wrx`9@{qQ^-q>gf*SX2vn(T3he2#mBZ=18IIo;-c+NAX^Hy3-{|KUIB z;enEF5{gl&%~xF{~S^j6%LF8?s`cxaZ-vh?lDeFVdQ&MBb@06hDg$^ZZW literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/LeavesPine.png b/src/main/resources/assets/textures/blocks/LeavesPine.png new file mode 100644 index 0000000000000000000000000000000000000000..f01e1272c1bc4b150b434fdfadb93d5a1cc4de14 GIT binary patch literal 6521 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 KMNUMnLSTXhkb}wq literal 7213 zcmV+|9Ma>7P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*rawI!;h5us}S^~UT4s3*Wpylg3$gCp!&6|l) zXqwS9$*N4?nqw|#_W%6%G5^KClwvk9m6}`5mVdFu<~!e1`~2(ov$OGjet!7;&i#4a ze1GA&6!;pRA8UTEZ?1b@@89e5y-(+Q`gNnW-(QSBf6?C?`T9QKz5aPnaL)tmdt=kz z8wLM9IX*v+XInP6T7GX~zOO&;?{66RZ}cgK;&aNbL_SAvOUaGztGBTbx21)i>6_k{ z#(Sf`{A@li^{mP7;DY6I)e3|DyU_Vs`Rw`q&lSt(5c0E9vgM5}eBVBC{n!8g)ymCh z>2J#aNa^=G_fM|>%Cxxw{rn>QB}4i9^>44c^mE<(PU+3tuP5jHeexgI!~W#vWSPM!$XGtM`*sPQ%4YGMb;H)P<-IcYFygEYj}7q#OcQ{dX9JuoaHQfMzKK}Yoc@1PR z-7r@+*zM3ANdHLgr?|pRbl`=FuTPR)S?>)95i3Y6#sxB9vkS>(XN&iyI7c8W3F<7} zhv)}saVh!5B7LNxNDf`Vvw2T(_oY7h=Q2P@B2vgE6mru-Cs{E9nKW^whI$Gqrj&9j zsiu~C4p|+RbIC%~UP6f_m0U`xrIl`KsIjJ+YpJ!i+M90y#7&KUY_+x4I}h#Lx%2MM z3wj@Zgb_y?d6ZE{8-02+!;CY{Jj<-J&A$8!i#}d?l~q?;eY;I5?YPsgkn7jA~sh6<_;M|1$`92T-q*eg-Qt~O#A+T6v>M3~o(d8};Oin}!%BjGFheQ3Rw zIeA}%mrKfhjk8iaedT=GUc36fS0@ z%4etyU81PeND5u)!P`A+YrN;&!I)iIJWarOVp_1 zK^TLNqlmm*TP0~JMN3iOcN*diplk7Zp4IHwJwr#X#ajAutw*nYoZX1NJCVI?!j}EW zd60qy*AzQr4xj5OOv)(oz&VXQROlhDak#QKtuczoXnQKTE@ezhqiJ|}6_ciULb9c0 zg70Y@+6go^VNVB56qXUf*>ou{u;exPKBJ?ujyktRdcM)eF4h{$87sx&Qg;MqcP^N* z4g{AZ^=8et(sJ5V8ap^3H=AZ(ha$S=q1_ENJ!I%!Ec$$CWP~Duc`eMKTE~BLSe~Z7q zbv;htn0&a;3V4ycnlDDwipEsCHx><06cQNEB(haynCVuc-bko-8EVjTN)pFe{g^I_ zIumBklu`r|$E2#+4|vLNfI@o6*TVw{CK{J8Z_1#IO)7R>Lej*&EKQ$Hr}C~~quI8j zxIn410Jd47AK;lE6t`Zf59*w*o=2-11tg}aLP7WuBM^HFnX;cbczAu&sV|R&*|b{t zAf7+UpxiQ`MKW!g5L(q67m6LMnSwzzP{|aYUJNsphneW!D^(H=5cebmCH71byw;lt zMg~8PyTJ!t!apJfCIPS820{ok*r}UBr!Af^EBaFv7b$FU08EP_UjPKF<5!T&A4pBl z_#Pl{-dmEg_sLZGV-R{3MF(zuA5qG3L5$Dan*PbN}cycML6=V0Hwi7 z;=1y=zZ~SsYUT#*Dwi&;=o1`@Zo_v$Rn#-ZFZLa=A2^&C)hJ8be4+@O1E@wY2f~Q# zh)|ZE5t5S=I1zM7s~E%% z9&t)Z16)%Gk_(b43)$&cno~3rr*#h=CzvSH);lI@L)=5J&29j8qQlRp!Gx$1RtxD3 zlsU;XKUSwzVBPf=4o?3YWuCENT1mS7g?$=gL62iJKokSuLXD>09iMXYigOjjG z$7A0>NSpFx*_pcMJ!=_guxvDDgVrS-K~`buEm9;kjk0j>2!1*fDFQC6qQXH=q#`wN zyW~kfh-L9^2ifRe9!0#7d%zTuX!4KR+{$UCJ%aG@LT|R}D#TE|YJ}w6oBwV>eDB(l zupPauuMdmEEP-MeY2ggwHLs{4mGL$c3O(aUf)({$(5~tMHjlW3o*6_FdCr%eiomEt z!vvTd*MMGcZOk&v@?wFkTH2-gtHLU3Ug5VFNhLQjxn^>0ibe?V!de5%4#gz93@RWSMnsN+rr-$u_~$aby+k^RIh(&~eR3WJ8uDDzhpcvDh=xBI}W%!o)4#56GfI*Ya&@Y%Y z8M)-Z5IdV!Ke#8)0hs7xR=moR3Ut4F8~+GzM1y2tvEe$wi6I3S8xR|$XFz8mgL1jJ z9;B<$$ABFTj(YRU&YUAH+KwsG?!rt8yvUy&O@?JkQ2P{0J|26CclALx_kzG*QY!)( z9O4nC#i!A2z+4Mp`z-23N43_7dad-L*y_KS|DW=$z>%Np>>s) zGPn^|VO=1u>N8-~e__=+`Xg>OB7;Byqt^j6k)VSEgz_kgBnEjJmXsj%fpHm-+t$1t)OvgUxi-`mAPQ(b%sA-WfQW`mn%LIC zG5{2BqLUC2!bzkIA*W2|spBX~O=L!ACEB4En#Mep91{`2=`Ii21q~52z2V;K-=Hxm zkfixh!?t%IYO63Q(RDr5vCFWRA_*)#+h`;|HwOAsUG|}JKsNZR1qrKx2{3^M33HC&cuWWbjYgj&_y_gN-k>Tyy-%}HMr>EdI9$c^8kPW130%1 zlL^S`qh;vG@2dSa>U%_xV5&ITJ+z=4%+l0x+VhE)$J{)6roboxG!2(oj8sS0l6c3-PSTYe!SE!?x@AYl7lae?A&h1pqZTI2O8H~9zT)$7rTt1bJ;Z3hiSBMF z1c^!D;VB3b(x_8M^%M&kjfyyC)5PZE{WLDkf`@9Gm-2TQyP=tR(-k>dh&6Ny&tZF; z1};S`P*s}wvBcqMa<$)Ar=P{ojosOP?+7;Vc2@xCW4$cm z9SqwI>g8fIvwI8*^6%r-7S&c4{D_tUH-MfJFLGDGRXkM3RWJQV>=-o{T$38~QD7rM z@#DH8pzfX#m5i?U#UrSrbSz{764d=`7G^Z!Letj;{Ys{??vKqzHK5Z%W@iZ_r-R>d z?NM2k1WMxXtWKLWlleGmmK##dQe1@pdd0quufz`HbOoQ)fgb2e?{ei1$S155x)b+P z`Yny*9(i1zFrORd3B@iAP)C-_eCJtU5>9Su^1{2G8=_K?HTF)_M*8bu9Gcp5)OO{u zbU?a64nbyz`ou3cn+uQ3NmjI9(KBk$RA7odpQ#K?JqQXB(+ucHMH5XD8n9~qp21+) zc>c2sokFC~;6y8VrexQx;n7nNhrBY$GA{IfW z{ESIi^BuQzX|(TvCTik?8xnyFeOsgVKv8oSGMa>*NXBY{AvGJ2T&sm^e*j>-kLuEE z8oZYzMv-|=7%gfeOl#D@mq9g`(eVvPD!>9K7F8Xsya}688u5EW@TZZ^d@{0CMirxL zq*Ef9*t<=SNS@-HaY?WIXnml&rZt0|8kC56x*%fpSLwuM04|EN>lT|^JSRMq6at02 zNWEl9uX2}!1ktSQ&%rODozRg6bth_ID~iB65s8U2IekAAu%}ewU*rsG1{gxcpVjF{ zm%B-I&4H5LK?P-j=6&UW4%R%8#F8u&N!l7S<@nL}-1R%KN}4~I@2@a)m_dXurNnLJ zaPKUn4jA$k|ML<5zDoL_M96P%cUV{cQjm~M5qkqWu^g9TzY)``4;=M%d%K@#HNf`Q4<_vExHONW9gumbyy{mRlMy9bQU@HVHnGg-IO+nZYX@hx5wQLRW)a(Ys zqtPJ3S#0VNWEws~vT*Ij*UH<|*jb>VQ67q--{D%uH{or=1cWFTBgh8sZDbxZE!yWgbaqz6v#zrq_6b%5IJA|Q7HHIua+JS?VZ(t9hx`imt=`h=>D3KH70Jl-V*kSWv8(-Va` zCXKFf37mUJFJ3a6a-ez<(jd{19)=+QMyNP>s9%stsi+gb1Ei|I8OoZQ3XE8<{1kyjB=(x&*hd!l3F9mt_@lKA^oFwZ(A zVEY_-qmJl8aIjfTHJW_HYwt|EV)(B^Q{~db*|HpPQFBtK@z*@*Axzk~rb)M@W*`F% zIneYckBn_f&-s9sY^?v=72yDm&P38rr#(l)K=cOv zpk$~#7b^FGlAw(}nu)h^Jk~(Xk1>@sVs2@^wcln_&Fr z1xFp1j<~7kb8x8isP)U$cE65V(I)q-EmzWygPiz{c0T#h$?=aM4Hso7oix=sY5Zvr z?#e-zEGw$TU44W=X~`jk=0XN#{k6&*I&{~}AG8EG)iyf4A^_|pBh_z%lwc6t8sBOV zRoSv7umfbtlgh**KxHDZRL1%_IC$$Z&ugPW+TpT!=ISy*_o(K890aC1>K-_lU6C9r@sOwYhi736I z8UDfH1$z*qcS@^r0KVAsmejlhmP*zwss=q@BrP&*XV0@h$s|a}Wvd|!`!=`!SmZqz z2J2xlbr>Kh%2xe33T!iVmIK>G7Kb{g7)Sac$)aN_Cr7zQ z&@nvvh_|sx9Wh8Le1c$OB78(8hxj=XAN?6W<5GD{tG*;T7Oy{VFh^MUoO;=T^#S>h z{x*f%t1woA?ACLdS#)Tu*~;r4Ta0A7Q1S9><(_tYp!C(c+2zxLY^>isGq#GJ4srEI zCm);^T&a63t}Nh=#?pX=SR`s*qcJ@*VGBa|HTwe%u_K`7&!FdL&ZC1=bIxk!e*qGb z!JdilJvIOU00v@9M??VP0OA1RPc^7o00009a7bBm001r{001r{0eGc9b^rhX2XskI zMF-^w77_p@oB6;>0000PbVXQnLvL+uWo~o;Lvm$dbY)~9cWHEJAV*0}P*;Ht7XSbS zlSxEDR7l4?mDz4wxfMkh56L@KsY;_IyQG%8ZP*#$AIO*F#{+Z#BaS9(D2+AU%Q+8a z$Jdf`Mr+OPbcg-v9zU+GNGYSWa5kF}g6D2NC#Qlnn!VjADMl9S zHA)FFM)vpj2;TGj@`^EroHKv_@)sn;z+^JP`GM7Hg^v+y4O$EPyHi92C4yE$N|BT^ zDQ23kBZP=^o)i_~WIP^|bB0oQTQ88w&JKOw)7CAgvl*2!C?x=lx{l>~MTn7@ z5-|ppQjB-T7;UhXMMR-Qark*DD6^h%r+)6{QsRCR46{ z-ZCAH5w-&-lPNi8`hJ5ohMW>2f-#!?{e5!I#1tuj(UyPx`6m)%psFe;g`M#j7bD(# z-d0OePOSS4wl?IHNiiZyAqXi(Voc&c*LSy6mBssjXoZN7bLQpcb-R^pb(EA6r4;&MgZG{k zBMOBNo}4omS6AC}Omw4;^V1p54J?-nLWlr}(bRQ=Hio8asOpNUvgDkRQVM_j`W0g; zcBi`lTOmgyN+~$!d3cypHxhB2^PbVDV>}))nT!w-LQIGfL==;q2~AUj+J0Hv zHHZ(Mi|ZQzVu-BP8$wDLZD`w;^|0aO-4Otl(fs%FlFg<^WGi$?o&*&E z!5T}95ozm&%2rfW#s1zdb=9!htZ>dT3lIKa zxiAa^tM!JvyL(D0T>reqSWR6uNX&tp3&t2ep3XRaceo`<1g$kbM*4mrIES?stu>RK z9UdN@FvgNg-iBMs_z)P6$5^9LC`L_(v`t5hk_)Tg;EM@EzUXme#6(#pAoHp z#e(6t^WT`A9FtN)YfT7&wrx0@ePF%b5PU?m=HmJSsj7;uYthE=Fn{9k;EZ^o+Fz=OazsqDmpB#D6X?S*)7-gwAQq32SCml)6_M&6x=Yd zczvU)EN$D-bPee_0mA+K0c$NjMU+yc6j>}^X`6=eXiSLl|6rt)Kq-s}_wz^OZTUu_ zaBy(I;nCJC>(z?uo1Z|zxdCl7Rb{c-Fr7{j(HtM0&<_J4Mhbgj77+lY|+hPA;7Yg)4Pi?Dh@sBz}j9lGcbMo$phsP(Div`*k vQqDX)KG8HaZPzfL&j~4!V@9-4*A4#zj-@$tz8IdU00000NkvXXu0mjf6<4EL diff --git a/src/main/resources/assets/textures/blocks/LogTop.png b/src/main/resources/assets/textures/blocks/LogTop.png index fb61de591b093117c175c363f463e61dfa1db4ab..99adc8997c407be90898523bab85ff15a099dc93 100644 GIT binary patch delta 6616 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 Ww^jOkR5A)s1Y!o3gV9Vo(DM6p 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 Z^FLzu9_^002ovPDHLkV1kN}E9(FN