Skip to content

Commit

Permalink
Improve: add clamp mod and use world coordinate mode to bezier curve …
Browse files Browse the repository at this point in the history
…block.

Bump Version to 1.4.41

Took 1 hour 36 minutes
  • Loading branch information
xkball committed Dec 9, 2024
1 parent 0984a0c commit 447b9f2
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 31 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mod_name=Power Tool
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=GPL-3.0
# The mod version. See https://semver.org/
mod_version=1.4.40
mod_version=1.4.41
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class BezierCurveBlockEntity extends BlockEntity implements IClientUpdate
public int uScale = 1;
public int vScale = 1;
public int color = -1;
public boolean clampMode = false;
public boolean worldCoordinate = false;
public ResourceLocation texture = VanillaUtils.MISSING_TEXTURE;
public List<Vector3f> controlPoints = new ArrayList<>();
public BezierCurve3f bezierCurve;
Expand Down Expand Up @@ -72,6 +74,8 @@ public void read(CompoundTag tag) {
if(tag.contains("uScale")) uScale = tag.getInt("uScale");
if(tag.contains("vScale")) vScale = tag.getInt("vScale");
if(tag.contains("texture")) texture = Objects.requireNonNullElse(ResourceLocation.tryParse(tag.getString("texture")),VanillaUtils.MISSING_TEXTURE);
if(tag.contains("clampMode")) clampMode = tag.getBoolean("clampMode");
if(tag.contains("worldCoordinate")) worldCoordinate = tag.getBoolean("worldCoordinate");
if(tag.contains("controlPointSize")){
var size = tag.getInt("controlPointSize");
controlPoints = new ArrayList<>();
Expand All @@ -93,6 +97,8 @@ public CompoundTag write(CompoundTag tag) {
tag.putInt("uScale", uScale);
tag.putInt("vScale", vScale);
tag.putString("texture", texture.toString());
tag.putBoolean("clampMode", clampMode);
tag.putBoolean("worldCoordinate", worldCoordinate);
for(int i = 0; i < controlPoints.size(); i++){
tag.putFloat("controlPoint"+i+"x", controlPoints.get(i).x());
tag.putFloat("controlPoint"+i+"y", controlPoints.get(i).y());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.Checkbox;
import net.minecraft.client.gui.components.Tooltip;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -31,6 +33,8 @@ public class BezierCurveBlockScreen extends Screen {
protected ObjectInputBox<Integer> vScaleInput;
protected ObjectInputBox<Integer> colorInput;
protected ObjectInputBox<ResourceLocation> textureInput;
protected Checkbox useClampMode;
protected Checkbox useWorldCoordinate;


public BezierCurveBlockScreen(BezierCurveBlockEntity te) {
Expand All @@ -42,42 +46,54 @@ public BezierCurveBlockScreen(BezierCurveBlockEntity te) {
protected void init() {
super.init();
var startY = (int)(height*0.05);

var startX = (int)(width*0.2);
this.addRenderableWidget(new Button.Builder(CommonComponents.GUI_DONE, btn -> this.onDone())
.pos((int) (this.width*0.2), (int) Math.max(startY*2+20+25*7,this.height*0.8 + startY))
.size((int) (width*0.2), 20).build());
.pos(startX, (int) Math.max(startY*2+20+25*9,this.height*0.8 + startY))
.size(startX, 20).build());

this.stepInput = new ObjectInputBox<>(font, (int) (width*0.2),startY*2+20, (int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.step"),ObjectInputBox.INT_VALIDATOR.and(str -> {
this.stepInput = new ObjectInputBox<>(font, startX,startY*2+20, (int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.step"),ObjectInputBox.INT_VALIDATOR.and(str -> {
var i = Integer.parseInt(str);
return i>=2 && i < 2000;
}),ObjectInputBox.INT_RESPONDER);
this.stepInput.setMaxLength(14);
this.stepInput.setValue(String.valueOf(Math.max(te.steps,2)));
this.addRenderableWidget(this.stepInput);
this.sideCountInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.sides"),ObjectInputBox.INT_VALIDATOR.and(str -> Integer.parseInt(str) >= 3),ObjectInputBox.INT_RESPONDER);
this.sideCountInput = new ObjectInputBox<>(font,startX,startY*2+20+25,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.sides"),ObjectInputBox.INT_VALIDATOR.and(str -> Integer.parseInt(str) >= 3),ObjectInputBox.INT_RESPONDER);
this.sideCountInput.setMaxLength(14);
this.sideCountInput.setValue(String.valueOf(Math.max(te.sideCount,3)));
this.addRenderableWidget(this.sideCountInput);
this.radiusInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25*2,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.radius"),ObjectInputBox.FLOAT_VALIDATOR,ObjectInputBox.FLOAT_RESPONDER);
this.radiusInput = new ObjectInputBox<>(font,startX,startY*2+20+25*2,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.radius"),ObjectInputBox.FLOAT_VALIDATOR,ObjectInputBox.FLOAT_RESPONDER);
this.radiusInput.setMaxLength(14);
this.radiusInput.setValue(String.valueOf(te.radius));
this.addRenderableWidget(this.radiusInput);
this.textureInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25*3,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.texture"),ObjectInputBox.TEXTURE_VALIDATOR,ObjectInputBox.TEXTURE_RESPONDER);
this.textureInput = new ObjectInputBox<>(font,startX,startY*2+20+25*3,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.texture"),ObjectInputBox.TEXTURE_VALIDATOR,ObjectInputBox.TEXTURE_RESPONDER);
this.textureInput.setMaxLength(1000);
this.textureInput.setValue(te.texture.toString());
this.addRenderableWidget(this.textureInput);
this.uScaleInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25*4,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.uScale"),ObjectInputBox.INT_VALIDATOR,ObjectInputBox.INT_RESPONDER);
this.uScaleInput = new ObjectInputBox<>(font,startX,startY*2+20+25*4,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.uScale"),ObjectInputBox.INT_VALIDATOR,ObjectInputBox.INT_RESPONDER);
this.uScaleInput.setMaxLength(14);
this.uScaleInput.setValue(String.valueOf(te.uScale));
this.addRenderableWidget(this.uScaleInput);
this.vScaleInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25*5,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.vScale"),ObjectInputBox.INT_VALIDATOR,ObjectInputBox.INT_RESPONDER);
this.vScaleInput = new ObjectInputBox<>(font,startX,startY*2+20+25*5,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.vScale"),ObjectInputBox.INT_VALIDATOR,ObjectInputBox.INT_RESPONDER);
this.vScaleInput.setMaxLength(14);
this.vScaleInput.setValue(String.valueOf(te.vScale));
this.addRenderableWidget(this.vScaleInput);
this.colorInput = new ObjectInputBox<>(font,(int) (width*0.2),startY*2+20+25*6,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.color"),ObjectInputBox.RGB_COLOR_VALIDATOR,ObjectInputBox.RGB_COLOR_RESPONDER);
this.colorInput = new ObjectInputBox<>(font,startX,startY*2+20+25*6,(int) (width*0.25),20,Component.translatable("powertool.gui.bezier_curve.color"),ObjectInputBox.RGB_COLOR_VALIDATOR,ObjectInputBox.RGB_COLOR_RESPONDER);
this.colorInput.setMaxLength(14);
this.colorInput.setValue(VanillaUtils.hexColorFromInt(te.color));
this.addRenderableWidget(this.colorInput);
this.useClampMode = Checkbox.builder(Component.translatable("powertool.gui.bezier_curve.use_clamp_mode"),font)
.tooltip(Tooltip.create(Component.translatable("powertool.gui.bezier_curve.use_clamp_mode.tooltip")))
.pos(startX,startY*2+20+25*7)
.selected(te.clampMode)
.build();
this.addRenderableWidget(this.useClampMode);
this.useWorldCoordinate = Checkbox.builder(Component.translatable("powertool.gui.bezier_curve.use_world_coordinate"),font)
.tooltip(Tooltip.create(Component.translatable("powertool.gui.bezier_curve.use_world_coordinate.tooltip")))
.pos(startX,startY*2+20+25*8)
.selected(te.worldCoordinate)
.build();
this.addRenderableWidget(this.useWorldCoordinate);
this.append = Button.builder(Component.literal("+"),(b) -> {
if(this.vector3fList != null) vector3fList.appendEntry();
}).size(20,20).pos((int) (width*0.95-25),startY+20).build();
Expand All @@ -102,6 +118,8 @@ public void removed() {
te.uScale = Objects.requireNonNullElse(uScaleInput.get(),1);
te.vScale = Objects.requireNonNullElse(vScaleInput.get(),1);
te.color = Objects.requireNonNullElse(colorInput.get(),-1);
te.clampMode = useClampMode.selected();
te.worldCoordinate = useWorldCoordinate.selected();
var points = vector3fList.entries().stream().map(Vector3fList.Entry::getResult).toList();
te.setControlPoints(points);
PacketDistributor.sendToServer(UpdateBlockEntityData.create(te));
Expand All @@ -115,7 +133,7 @@ public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partia
var startY = (int)(height*0.05);
guiGraphics.drawString(font,s1,(int)(width*0.55)+5,startY+20+5,-1);
guiGraphics.drawString(font,s2,(int)(width*0.55)+5, (int) (startY+20+height*0.8)+5,-1);
if(te.bezierCurve != null) guiGraphics.drawString(font,"length: "+te.bezierCurve.getLength(),(int) (width*0.2),startY*2+20+25*7,-1);
if(te.bezierCurve != null) guiGraphics.drawString(font,"length: "+te.bezierCurve.getLength(),(int) (width*0.2),startY*2+20+25*9,-1);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.datafixers.util.Pair;
import net.minecraft.world.level.ChunkPos;
import org.teacon.powertool.client.eyelib.render.sections.BlockEntitySectionGeometryRenderer;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -40,10 +41,20 @@ public AABB getRenderBoundingBox(BezierCurveBlockEntity blockEntity) {
public void renderSectionGeometry(BezierCurveBlockEntity te, AddSectionGeometryEvent.SectionRenderingContext context, PoseStack poseStack, BlockPos pos, BlockPos regionOrigin, int packedLight, MultiBufferSource bufferSource) {
var model = te.line;
if(model == null) return;
var line = model.line;
var clampMode = te.clampMode;
var steps = te.steps;
var sideCount = te.sideCount;
var vertexList = model.vertexAndNormalQuadsList();
if(vertexList.size() < (te.steps-1)*te.sideCount*4) return;
var level = Minecraft.getInstance().level;
var selfPos = te.getBlockPos();
var useWorldCoordinate = te.worldCoordinate;
BlockPos centerPos = null;
if(level != null) centerPos = level.getChunkAt(selfPos).getPos().getMiddleBlockPosition(0);
if(vertexList.size() < (steps-1)*sideCount*4) return;
poseStack = context.getPoseStack();
poseStack.pushPose();
if(useWorldCoordinate) poseStack.translate(-selfPos.getX(), -selfPos.getY(), -selfPos.getZ());
@SuppressWarnings("deprecation")
var texture = Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(te.texture);
var pose = poseStack.last();
Expand All @@ -53,10 +64,11 @@ public void renderSectionGeometry(BezierCurveBlockEntity te, AddSectionGeometryE
var color = te.color;
var u = 0f;
var v = 0f;
for(var i = 0; i < te.steps-1; ++i) {
for(var i = 0; i < steps-1; ++i) {
v = 0f;
for(var j = 0; j < te.sideCount; ++j) {
var ptr = j*4+i*te.sideCount*4;
if(centerPos != null && clampMode && !insideRenderChunk(centerPos,line.get(i), useWorldCoordinate ? 0 : selfPos.getX(), useWorldCoordinate ? 0 : selfPos.getZ())) continue;
for(var j = 0; j < sideCount; ++j) {
var ptr = j*4+i*sideCount*4;
putVertex(buffer,pose,vertexList.get(ptr),texture.getU(u),texture.getV(v), color, packedLight);
putVertex(buffer,pose,vertexList.get(ptr+1),texture.getU(u+uScale),texture.getV(v), color, packedLight);
putVertex(buffer,pose,vertexList.get(ptr+2),texture.getU(u+uScale),texture.getV(v+vScale), color, packedLight);
Expand All @@ -74,6 +86,10 @@ public void renderSectionGeometry(BezierCurveBlockEntity te, AddSectionGeometryE
poseStack.popPose();
}

public static boolean insideRenderChunk(BlockPos chunkCenter,Vector3f renderPos,int offsetX,int offsetZ){
return Math.abs(chunkCenter.getX()-renderPos.x-offsetX) < 10f && Math.abs(chunkCenter.getZ()-renderPos.z-offsetZ) < 10f;
}

public static void putVertex(VertexConsumer buffer, PoseStack.Pose pose, Pair<Vector3f,Vector3f> vertexAndNormal, float u, float v, int color, int light){
var vertex = vertexAndNormal.getFirst();
var normal = vertexAndNormal.getSecond();
Expand Down
36 changes: 21 additions & 15 deletions src/main/java/org/teacon/powertool/utils/math/Line3f.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class Line3f {
public final Vector3f start;
public final Vector3f end;
public final List<Vector3f> line;
private List<Pair<Vector3f,Vector3f>> vertexesAndNormals;
private volatile List<Pair<Vector3f,Vector3f>> vertexesAndNormals;
private final Object lock = new Object();

/**
* constructor of a line can be rendered in world.
Expand All @@ -43,23 +44,28 @@ public Line3f(int sideCount, double radius, List<Vector3f> line){
nodes.add(new LineNode3f(line.getLast(), previous,null, sideCount,radius));
}

//是的这真有可能多线程访问[xkball]
public synchronized List<Pair<Vector3f,Vector3f>> vertexAndNormalQuadsList(){
//是的这真有多线程访问[xkball]
public List<Pair<Vector3f,Vector3f>> vertexAndNormalQuadsList(){
if(vertexesAndNormals == null){
vertexesAndNormals = new ArrayList<>();
for(var i = 0; i < (nodes.size() - 1); i++){
var cur = nodes.get(i);
var next = nodes.get(i + 1);
var sideCount = cur.sideCount;
for(int j = 0; j < sideCount; j++){
vertexesAndNormals.add(Pair.of(cur.points.get(j),cur.normals.get(j)));
vertexesAndNormals.add(Pair.of(next.points.get(j),next.normals.get(j)));
var jNext = (j+1)%sideCount;
vertexesAndNormals.add(Pair.of(next.points.get(jNext),next.normals.get(jNext)));
vertexesAndNormals.add(Pair.of(cur.points.get(jNext),cur.normals.get(jNext)));
synchronized (lock){
if(vertexesAndNormals == null){
var temp = new ArrayList<Pair<Vector3f,Vector3f>>();
for(var i = 0; i < (nodes.size() - 1); i++){
var cur = nodes.get(i);
var next = nodes.get(i + 1);
var sideCount = cur.sideCount;
for(int j = 0; j < sideCount; j++){
temp.add(Pair.of(cur.points.get(j),cur.normals.get(j)));
temp.add(Pair.of(next.points.get(j),next.normals.get(j)));
var jNext = (j+1)%sideCount;
temp.add(Pair.of(next.points.get(jNext),next.normals.get(jNext)));
temp.add(Pair.of(cur.points.get(jNext),cur.normals.get(jNext)));
}
}
vertexesAndNormals = Collections.unmodifiableList(temp);
}
}
vertexesAndNormals = Collections.unmodifiableList(vertexesAndNormals);

}
return vertexesAndNormals;
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/assets/powertool/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,9 @@
"powertool.gui.bezier_curve.color": "Color(ARGB)",
"powertool.gui.bezier_curve.control_points": "Control Points: ",
"powertool.gui.bezier_curve.control_points_warn": "For performance reasons, it is recommended that the number of control points be less than four.",
"powertool.gui.bezier_curve.use_clamp_mode": "Use Clamp Mode",
"powertool.gui.bezier_curve.use_clamp_mode.tooltip": "Will not render vertexes far from chunk center.",
"powertool.gui.bezier_curve.use_world_coordinate": "Use World Coordinate",
"powertool.gui.bezier_curve.use_world_coordinate.tooltip": "Determines whether control points represent relative or absolute(world) coordinates.",
"powertool.gui.examine_holo_glass.warn": "Calculated independently relative to the left side."
}
4 changes: 4 additions & 0 deletions src/main/resources/assets/powertool/lang/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,9 @@
"powertool.gui.bezier_curve.color": "颜色(ARGB)",
"powertool.gui.bezier_curve.control_points": "控制点: ",
"powertool.gui.bezier_curve.control_points_warn": "出于性能考虑,建议控制点个数在四个以下",
"powertool.gui.bezier_curve.use_clamp_mode": "使用限制渲染模式",
"powertool.gui.bezier_curve.use_clamp_mode.tooltip": "将不会渲染远离区块中心的顶点.",
"powertool.gui.bezier_curve.use_world_coordinate": "使用世界坐标",
"powertool.gui.bezier_curve.use_world_coordinate.tooltip": "决定控制点代表相对坐标还是绝对(世界)坐标.",
"powertool.gui.examine_holo_glass.warn": "相对左侧独立计算."
}

0 comments on commit 447b9f2

Please sign in to comment.