1+ package com.lambda.graphics.renderer.esp
2+
3+ import com.lambda.context.SafeContext
4+ import com.lambda.event.events.RenderEvent
5+ import com.lambda.event.events.TickEvent
6+ import com.lambda.event.listener.SafeListener.Companion.listener
7+ import com.lambda.graphics.buffer.vao.VAO
8+ import com.lambda.graphics.buffer.vao.vertex.VertexAttrib
9+ import com.lambda.graphics.buffer.vao.vertex.VertexMode
10+ import com.lambda.graphics.renderer.esp.DirectionMask.DOWN
11+ import com.lambda.graphics.renderer.esp.DirectionMask.EAST
12+ import com.lambda.graphics.renderer.esp.DirectionMask.NORTH
13+ import com.lambda.graphics.renderer.esp.DirectionMask.SOUTH
14+ import com.lambda.graphics.renderer.esp.DirectionMask.UP
15+ import com.lambda.graphics.renderer.esp.DirectionMask.WEST
16+ import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection
17+ import com.lambda.graphics.shader.Shader
18+ import com.lambda.util.primitives.extension.max
19+ import com.lambda.util.primitives.extension.min
20+ import com.lambda.util.primitives.extension.partialTicks
21+ import com.lambda.util.primitives.extension.prevPos
22+ import net.minecraft.entity.Entity
23+ import net.minecraft.util.math.Box
24+ import java.awt.Color
25+
26+ object EntityEspRegistry {
27+ private val filled = VAO (VertexMode .TRIANGLES , VertexAttrib .Group .DYNAMIC_RENDERER )
28+ private val outline = VAO (VertexMode .LINES , VertexAttrib .Group .DYNAMIC_RENDERER )
29+ private val shader = Shader (" renderer/pos_color" , " renderer/box_dynamic" )
30+
31+ fun renderEntityESP (owner : Any , block : SafeContext .(Renderer ) -> Unit ) {
32+ owner.listener<TickEvent .Post > {
33+ block(Renderer )
34+ }
35+ }
36+
37+ object Renderer {
38+ fun build (entity : Entity , filledColor : Color , outlineColor : Color , sides : Int = DirectionMask .ALL , outlineMode : DirectionMask .OutlineMode = DirectionMask .OutlineMode .OR ) {
39+ buildFilled(entity, filledColor, sides)
40+ buildOutline(entity, outlineColor, sides, outlineMode)
41+ }
42+
43+ fun buildFilled (entity : Entity , color : Color , sides : Int = DirectionMask .ALL ) = filled.use {
44+ val box = entity.boundingBox
45+
46+ val delta = entity.prevPos.subtract(entity.pos)
47+ val prevBox = Box (box.min.add(delta), box.max.add(delta))
48+
49+ val pos11 = prevBox.min
50+ val pos12 = prevBox.max
51+ val pos21 = box.min
52+ val pos22 = box.max
53+
54+ grow(8 )
55+
56+ val blb by lazy { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color).end() }
57+ val blf by lazy { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color).end() }
58+ val brb by lazy { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color).end() }
59+ val brf by lazy { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color).end() }
60+ val tlb by lazy { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color).end() }
61+ val tlf by lazy { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color).end() }
62+ val trb by lazy { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color).end() }
63+ val trf by lazy { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color).end() }
64+
65+ if (sides.hasDirection(EAST )) putQuad(brb, brf, trf, trb)
66+ if (sides.hasDirection(WEST )) putQuad(blb, blf, tlf, tlb)
67+ if (sides.hasDirection(UP )) putQuad(tlb, tlf, trf, trb)
68+ if (sides.hasDirection(DOWN )) putQuad(blb, brb, brf, blf)
69+ if (sides.hasDirection(SOUTH )) putQuad(blf, brf, trf, tlf)
70+ if (sides.hasDirection(NORTH )) putQuad(blb, brb, trb, tlb)
71+ }
72+
73+ fun buildOutline (entity : Entity , color : Color , sides : Int = DirectionMask .ALL , outlineMode : DirectionMask .OutlineMode = DirectionMask .OutlineMode .OR ) = outline.use {
74+ val box = entity.boundingBox
75+
76+ val delta = entity.prevPos.subtract(entity.pos)
77+ val prevBox = Box (box.min.add(delta), box.max.add(delta))
78+
79+ val pos11 = prevBox.min
80+ val pos12 = prevBox.max
81+ val pos21 = box.min
82+ val pos22 = box.max
83+
84+ grow(8 )
85+
86+ val blb by lazy { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color).end() }
87+ val blf by lazy { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color).end() }
88+ val brb by lazy { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color).end() }
89+ val brf by lazy { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color).end() }
90+ val tlb by lazy { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color).end() }
91+ val tlf by lazy { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color).end() }
92+ val trb by lazy { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color).end() }
93+ val trf by lazy { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color).end() }
94+
95+ val hasEast = sides.hasDirection(EAST )
96+ val hasWest = sides.hasDirection(WEST )
97+ val hasUp = sides.hasDirection(UP )
98+ val hasDown = sides.hasDirection(DOWN )
99+ val hasSouth = sides.hasDirection(SOUTH )
100+ val hasNorth = sides.hasDirection(NORTH )
101+
102+ if (outlineMode.check(hasUp, hasNorth)) putLine(tlb, trb)
103+ if (outlineMode.check(hasUp, hasSouth)) putLine(tlf, trf)
104+ if (outlineMode.check(hasUp, hasWest)) putLine(tlb, tlf)
105+ if (outlineMode.check(hasUp, hasEast)) putLine(trf, trb)
106+
107+ if (outlineMode.check(hasDown, hasNorth)) putLine(blb, brb)
108+ if (outlineMode.check(hasDown, hasSouth)) putLine(blf, brf)
109+ if (outlineMode.check(hasDown, hasWest)) putLine(blb, blf)
110+ if (outlineMode.check(hasDown, hasEast)) putLine(brb, brf)
111+
112+ if (outlineMode.check(hasWest, hasNorth)) putLine(tlb, blb)
113+ if (outlineMode.check(hasNorth, hasEast)) putLine(trb, brb)
114+ if (outlineMode.check(hasEast, hasSouth)) putLine(trf, brf)
115+ if (outlineMode.check(hasSouth, hasWest)) putLine(tlf, blf)
116+ }
117+ }
118+
119+ init {
120+ listener<TickEvent .Post >(Int .MAX_VALUE ) {
121+ filled.clear()
122+ outline.clear()
123+ }
124+
125+ listener<TickEvent .Post >(Int .MIN_VALUE ) {
126+ filled.upload()
127+ outline.upload()
128+ }
129+
130+ listener<RenderEvent .World > {
131+ shader.use()
132+ shader[" u_TickDelta" ] = mc.partialTicks
133+ shader[" u_CameraPosition" ] = mc.gameRenderer.camera.pos
134+
135+ filled.render()
136+ outline.render()
137+ }
138+ }
139+ }
0 commit comments