Skip to content

Commit 66c4b08

Browse files
committed
Try to add lines
1 parent b4252d0 commit 66c4b08

File tree

10 files changed

+848
-3
lines changed

10 files changed

+848
-3
lines changed

common/src/main/kotlin/com/lambda/graphics/buffer/vertex/attributes/VertexAttrib.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ sealed class VertexAttrib(
8383
Vec3, Vec2, Color
8484
)
8585

86+
object LINE : Group(
87+
Vec2, Float, Color
88+
)
89+
90+
object MULTILINE : Group(
91+
Vec2, Float, Float, Float, Color
92+
)
93+
8694
val stride = attributes.sumOf { attribute ->
8795
attribute.size
8896
}

common/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,24 @@ class VertexBuilder(
9090
this.indices += index2
9191
}
9292

93+
/**
94+
* Adds triangle indices using 3 vertices
95+
*/
96+
fun buildTriangle(
97+
index1: Int, index2: Int, index3: Int
98+
) {
99+
direct?.let {
100+
it.indices.putInt(index1)
101+
it.indices.putInt(index2)
102+
it.indices.putInt(index3)
103+
return
104+
}
105+
106+
this.indices += index1
107+
this.indices += index2
108+
this.indices += index3
109+
}
110+
93111
/**
94112
* Creates a collection of indices from varargs
95113
* @return List of provided indices for element array buffer
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.graphics.renderer.esp.builders
19+
20+
import com.lambda.graphics.RenderMain
21+
import com.lambda.graphics.renderer.esp.DynamicAABB
22+
import com.lambda.graphics.renderer.esp.impl.DynamicESPRenderer
23+
import com.lambda.graphics.renderer.gui.LineRenderer
24+
import net.minecraft.util.math.Vec3d
25+
import java.awt.Color
26+
import org.joml.Vector2d
27+
import org.joml.Vector4f
28+
29+
/**
30+
* Draws a line in 3D space using the LineRenderer.
31+
*
32+
* @param points List of 3D points to connect with lines
33+
* @param color Color of the line
34+
* @param width Width of the line
35+
* @param dashiness Dashiness of the line (1.0 = solid, 0.0 = fully dashed)
36+
* @param dashPeriod Period of the dashes
37+
*/
38+
fun DynamicESPRenderer.drawLine(
39+
points: List<Vec3d>,
40+
color: Color,
41+
width: Double = 1.0,
42+
dashiness: Double = 1.0,
43+
dashPeriod: Double = 1.0
44+
) {
45+
if (points.size < 2) return
46+
47+
// Project 3D points to 2D screen coordinates
48+
val screenPoints = points.mapNotNull { point ->
49+
val screenPos = project3DTo2D(point) ?: return@mapNotNull null
50+
LineRenderer.Point(Vector2d(screenPos.x, screenPos.y), color)
51+
}
52+
53+
if (screenPoints.size < 2) return
54+
55+
// Draw the line using LineRenderer
56+
LineRenderer.lines(
57+
dashiness = dashiness,
58+
dashPeriod = dashPeriod,
59+
batching = false
60+
) {
61+
line(width) {
62+
screenPoints.forEach { point ->
63+
point(point.pos, point.color)
64+
}
65+
}
66+
}
67+
}
68+
69+
/**
70+
* Draws a line in 3D space using the LineRenderer.
71+
*
72+
* @param start Starting point of the line
73+
* @param end Ending point of the line
74+
* @param startColor Color at the start of the line
75+
* @param endColor Color at the end of the line
76+
* @param width Width of the line
77+
* @param dashiness Dashiness of the line (1.0 = solid, 0.0 = fully dashed)
78+
* @param dashPeriod Period of the dashes
79+
*/
80+
fun DynamicESPRenderer.drawLine(
81+
start: Vec3d,
82+
end: Vec3d,
83+
startColor: Color,
84+
endColor: Color = startColor,
85+
width: Double = 1.0,
86+
dashiness: Double = 1.0,
87+
dashPeriod: Double = 1.0
88+
) {
89+
// Project 3D points to 2D screen coordinates
90+
val startScreen = project3DTo2D(start) ?: return
91+
val endScreen = project3DTo2D(end) ?: return
92+
93+
// Draw the line using LineRenderer
94+
LineRenderer.lines(
95+
dashiness = dashiness,
96+
dashPeriod = dashPeriod,
97+
batching = false
98+
) {
99+
line(width) {
100+
point(Vector2d(startScreen.x, startScreen.y), startColor)
101+
point(Vector2d(endScreen.x, endScreen.y), endColor)
102+
}
103+
}
104+
}
105+
106+
/**
107+
* Draws a line between two dynamic boxes in 3D space using the LineRenderer.
108+
*
109+
* @param box1 First dynamic box
110+
* @param box2 Second dynamic box
111+
* @param color Color of the line
112+
* @param width Width of the line
113+
* @param dashiness Dashiness of the line (1.0 = solid, 0.0 = fully dashed)
114+
* @param dashPeriod Period of the dashes
115+
*/
116+
fun DynamicESPRenderer.drawLineBetweenBoxes(
117+
box1: DynamicAABB,
118+
box2: DynamicAABB,
119+
color: Color,
120+
width: Double = 1.0,
121+
dashiness: Double = 1.0,
122+
dashPeriod: Double = 1.0
123+
) {
124+
val box1Pair = box1.getBoxPair() ?: return
125+
val box2Pair = box2.getBoxPair() ?: return
126+
127+
val center1 = Vec3d(
128+
(box1Pair.first.minX + box1Pair.first.maxX) / 2,
129+
(box1Pair.first.minY + box1Pair.first.maxY) / 2,
130+
(box1Pair.first.minZ + box1Pair.first.maxZ) / 2
131+
)
132+
133+
val center2 = Vec3d(
134+
(box2Pair.first.minX + box2Pair.first.maxX) / 2,
135+
(box2Pair.first.minY + box2Pair.first.maxY) / 2,
136+
(box2Pair.first.minZ + box2Pair.first.maxZ) / 2
137+
)
138+
139+
drawLine(center1, center2, color, color, width, dashiness, dashPeriod)
140+
}
141+
142+
/**
143+
* Projects a 3D point to 2D screen coordinates.
144+
* Returns null if the point is behind the camera or outside the screen.
145+
*/
146+
private fun project3DTo2D(point: Vec3d): Vector2d? {
147+
// Create a 4D vector from the 3D point
148+
val vec4 = Vector4f(
149+
point.x.toFloat(),
150+
point.y.toFloat(),
151+
point.z.toFloat(),
152+
1f
153+
)
154+
155+
// Transform the point using the projection-model matrix
156+
RenderMain.projModel.transform(vec4)
157+
158+
// Check if the point is behind the camera
159+
if (vec4.w <= 0f) return null
160+
161+
// Perform perspective division
162+
vec4.div(vec4.w)
163+
164+
// Convert from normalized device coordinates (-1 to 1) to screen coordinates (0 to screen width/height)
165+
val screenX = (vec4.x * 0.5f + 0.5f) * RenderMain.screenSize.x.toFloat()
166+
val screenY = (1f - (vec4.y * 0.5f + 0.5f)) * RenderMain.screenSize.y.toFloat()
167+
168+
// Check if the point is outside the screen
169+
if (screenX < 0 || screenX > RenderMain.screenSize.x.toFloat() || screenY < 0 || screenY > RenderMain.screenSize.y.toFloat()) {
170+
return null
171+
}
172+
173+
return Vector2d(screenX.toDouble(), screenY.toDouble())
174+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.graphics.renderer.esp.builders
19+
20+
import com.lambda.graphics.RenderMain
21+
import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer
22+
import com.lambda.graphics.renderer.gui.LineRenderer
23+
import net.minecraft.util.math.Vec3d
24+
import java.awt.Color
25+
import org.joml.Vector2d
26+
import org.joml.Vector4f
27+
28+
/**
29+
* Draws a line in 3D space using the LineRenderer.
30+
*
31+
* @param points List of 3D points to connect with lines
32+
* @param color Color of the line
33+
* @param width Width of the line
34+
* @param dashiness Dashiness of the line (1.0 = solid, 0.0 = fully dashed)
35+
* @param dashPeriod Period of the dashes
36+
*/
37+
fun StaticESPRenderer.drawLine(
38+
points: List<Vec3d>,
39+
color: Color,
40+
width: Double = 1.0,
41+
dashiness: Double = 1.0,
42+
dashPeriod: Double = 1.0
43+
) {
44+
if (points.size < 2) return
45+
46+
// Project 3D points to 2D screen coordinates
47+
val screenPoints = points.mapNotNull { point ->
48+
val screenPos = project3DTo2D(point) ?: return@mapNotNull null
49+
LineRenderer.Point(Vector2d(screenPos.x, screenPos.y), color)
50+
}
51+
52+
if (screenPoints.size < 2) return
53+
54+
// Draw the line using LineRenderer
55+
LineRenderer.lines(
56+
dashiness = dashiness,
57+
dashPeriod = dashPeriod,
58+
batching = false
59+
) {
60+
line(width) {
61+
screenPoints.forEach { point ->
62+
point(point.pos, point.color)
63+
}
64+
}
65+
}
66+
}
67+
68+
/**
69+
* Draws a line in 3D space using the LineRenderer.
70+
*
71+
* @param start Starting point of the line
72+
* @param end Ending point of the line
73+
* @param startColor Color at the start of the line
74+
* @param endColor Color at the end of the line
75+
* @param width Width of the line
76+
* @param dashiness Dashiness of the line (1.0 = solid, 0.0 = fully dashed)
77+
* @param dashPeriod Period of the dashes
78+
*/
79+
fun StaticESPRenderer.drawLine(
80+
start: Vec3d,
81+
end: Vec3d,
82+
startColor: Color,
83+
endColor: Color = startColor,
84+
width: Double = 1.0,
85+
dashiness: Double = 1.0,
86+
dashPeriod: Double = 1.0
87+
) {
88+
// Project 3D points to 2D screen coordinates
89+
val startScreen = project3DTo2D(start) ?: return
90+
val endScreen = project3DTo2D(end) ?: return
91+
92+
// Draw the line using LineRenderer
93+
LineRenderer.lines(
94+
dashiness = dashiness,
95+
dashPeriod = dashPeriod,
96+
batching = false
97+
) {
98+
line(width) {
99+
point(Vector2d(startScreen.x, startScreen.y), startColor)
100+
point(Vector2d(endScreen.x, endScreen.y), endColor)
101+
}
102+
}
103+
}
104+
105+
/**
106+
* Projects a 3D point to 2D screen coordinates.
107+
* Returns null if the point is behind the camera or outside the screen.
108+
*/
109+
private fun project3DTo2D(point: Vec3d): Vector2d? {
110+
// Create a 4D vector from the 3D point
111+
val vec4 = Vector4f(
112+
point.x.toFloat(),
113+
point.y.toFloat(),
114+
point.z.toFloat(),
115+
1f
116+
)
117+
118+
// Transform the point using the projection-model matrix
119+
RenderMain.projModel.transform(vec4)
120+
121+
// Check if the point is behind the camera
122+
if (vec4.w <= 0f) return null
123+
124+
// Perform perspective division
125+
vec4.div(vec4.w)
126+
127+
// Convert from normalized device coordinates (-1 to 1) to screen coordinates (0 to screen width/height)
128+
val screenX = (vec4.x * 0.5f + 0.5f) * RenderMain.screenSize.x.toFloat()
129+
val screenY = (1f - (vec4.y * 0.5f + 0.5f)) * RenderMain.screenSize.y.toFloat()
130+
131+
// Check if the point is outside the screen
132+
if (screenX < 0 || screenX > RenderMain.screenSize.x.toFloat() || screenY < 0 || screenY > RenderMain.screenSize.y.toFloat()) {
133+
return null
134+
}
135+
136+
return Vector2d(screenX.toDouble(), screenY.toDouble())
137+
}

0 commit comments

Comments
 (0)