@@ -3,17 +3,24 @@ package net.mullvad.mullvadvpn.compose.map.internal.shapes
3
3
import android.opengl.GLES20
4
4
import android.opengl.Matrix
5
5
import androidx.compose.ui.graphics.Color
6
- import net.mullvad.mullvadvpn.compose.map.internal.COLOR_COMPONENT_SIZE
7
6
import java.nio.FloatBuffer
8
7
import kotlin.math.cos
9
8
import kotlin.math.sin
10
- import net.mullvad.mullvadvpn.compose.map.internal.VERTEX_COMPONENT_SIZE
11
9
import net.mullvad.mullvadvpn.compose.map.data.LatLng
10
+ import net.mullvad.mullvadvpn.compose.map.internal.COLOR_COMPONENT_SIZE
11
+ import net.mullvad.mullvadvpn.compose.map.internal.VERTEX_COMPONENT_SIZE
12
12
import net.mullvad.mullvadvpn.compose.map.internal.initArrayBuffer
13
13
import net.mullvad.mullvadvpn.compose.map.internal.initShaderProgram
14
- import net.mullvad.mullvadvpn.compose.map.internal.toFloatArrayWithoutAlpha
14
+ import net.mullvad.mullvadvpn.compose.map.internal.toFloatArray
15
+
16
+ data class LocationMarkerColors (
17
+ val centerColor : Color ,
18
+ val ringBorderColor : Color = Color .White ,
19
+ val shadowColor : Color = Color .Black .copy(alpha = 0.55f),
20
+ val perimeterColors : Color = centerColor.copy(alpha = 0.4f)
21
+ )
15
22
16
- class LocationMarker (val color : Color ) {
23
+ class LocationMarker (val colors : LocationMarkerColors ) {
17
24
18
25
private val vertexShaderCode =
19
26
"""
@@ -42,37 +49,35 @@ class LocationMarker(val color: Color) {
42
49
"""
43
50
.trimIndent()
44
51
45
- private val white = floatArrayOf(1.0f , 1.0f , 1.0f )
46
- private val black = floatArrayOf(0.0f , 0.0f , 0.0f )
47
52
private val rings =
48
53
listOf (
49
54
circleFanVertices(
50
55
32 ,
51
56
0.5f ,
52
57
floatArrayOf(0.0f , 0.0f , 0.0f ),
53
- floatArrayOf( * color.toFloatArrayWithoutAlpha(), 0.4f ) ,
54
- floatArrayOf( * color.toFloatArrayWithoutAlpha(), 0.4f )
58
+ colors.perimeterColors ,
59
+ colors.perimeterColors,
55
60
), // Semi-transparent outer
56
61
circleFanVertices(
57
62
16 ,
58
63
0.28f ,
59
64
floatArrayOf(0.0f , - 0.05f , 0.00001f ),
60
- floatArrayOf( * black, 0.55f ) ,
61
- floatArrayOf( * black, 0.0f )
65
+ colors.shadowColor ,
66
+ colors.shadowColor.copy(alpha = 0.0f ),
62
67
), // shadow
63
68
circleFanVertices(
64
69
32 ,
65
70
0.185f ,
66
71
floatArrayOf(0.0f , 0.0f , 0.00002f ),
67
- floatArrayOf( * white, 1f ) ,
68
- floatArrayOf( * white, 1f )
72
+ colors.ringBorderColor ,
73
+ colors.ringBorderColor,
69
74
), // white ring
70
75
circleFanVertices(
71
76
32 ,
72
77
0.15f ,
73
78
floatArrayOf(0.0f , 0.0f , 0.00003f ),
74
- floatArrayOf( * color.toFloatArrayWithoutAlpha(), 1f ) ,
75
- floatArrayOf( * color.toFloatArrayWithoutAlpha(), 1f ) ,
79
+ colors.centerColor ,
80
+ colors.centerColor ,
76
81
) // Center colored circle
77
82
)
78
83
@@ -89,14 +94,14 @@ class LocationMarker(val color: Color) {
89
94
private val ringSizes: List <Int > = rings.map { (positions, _) -> positions.size }
90
95
91
96
init {
92
- val positionArrayBuffer = rings.flatMap { it.first }
93
- val positionByteBuffer = FloatBuffer .wrap(positionArrayBuffer.toFloatArray() )
97
+ val positionFloatArray = joinMultipleArrays( rings.map { it.vertices })
98
+ val positionFloatBuffer = FloatBuffer .wrap(positionFloatArray )
94
99
95
- val colorArrayBuffer = rings.flatMap { it.second }
96
- val colorByteBuffer = FloatBuffer .wrap(colorArrayBuffer.toFloatArray() )
100
+ val colorFloatArray = joinMultipleArrays( rings.map { it.verticesColor })
101
+ val colorFloatBuffer = FloatBuffer .wrap(colorFloatArray )
97
102
98
- positionBuffer = initArrayBuffer(positionByteBuffer )
99
- colorBuffer = initArrayBuffer(colorByteBuffer )
103
+ positionBuffer = initArrayBuffer(positionFloatBuffer )
104
+ colorBuffer = initArrayBuffer(colorFloatBuffer )
100
105
101
106
shaderProgram = initShaderProgram(vertexShaderCode, fragmentShaderCode)
102
107
@@ -164,28 +169,52 @@ class LocationMarker(val color: Color) {
164
169
private fun circleFanVertices (
165
170
numEdges : Int ,
166
171
radius : Float ,
167
- offset : FloatArray ,
168
- centerColor : FloatArray ,
169
- ringColor : FloatArray ,
170
- ): Pair <List <Float >, List<Float>> {
171
- val positions = mutableListOf (* offset.toTypedArray())
172
- val colors = mutableListOf (* centerColor.toTypedArray())
173
-
174
- for (i in 0 .. numEdges) {
175
-
176
- val angle = (i.toFloat() / numEdges.toFloat()) * 2f * Math .PI
177
- val x = offset[0 ] + radius * cos(angle).toFloat()
178
- val y = offset[1 ] + radius * sin(angle).toFloat()
179
- val z = offset[2 ]
180
- positions.add(x)
181
- positions.add(y)
182
- positions.add(z)
183
- colors.addAll(ringColor.toTypedArray())
172
+ offset : FloatArray = floatArrayOf(0.0f, 0.0f, 0.0f),
173
+ centerColor : Color ,
174
+ ringColor : Color ,
175
+ ): Ring {
176
+ // Edges + center + first point
177
+ val points = numEdges + 2
178
+
179
+ val positions = FloatArray (points * VERTEX_COMPONENT_SIZE )
180
+ val positionsColor = FloatArray (points * COLOR_COMPONENT_SIZE )
181
+
182
+ // Start adding the center the center point
183
+ offset.forEachIndexed { index, value -> positions[index] = value }
184
+ centerColor.toFloatArray().forEachIndexed { index, value -> positionsColor[index] = value }
185
+
186
+ val ringColorArray = ringColor.toFloatArray()
187
+
188
+ for (i in 1 until points) {
189
+
190
+ val angle = (i.toFloat() / numEdges) * 2f * Math .PI
191
+ val posIndex = i * VERTEX_COMPONENT_SIZE
192
+ positions[posIndex] = offset[0 ] + radius * cos(angle).toFloat()
193
+ positions[posIndex + 1 ] = offset[1 ] + radius * sin(angle).toFloat()
194
+ positions[posIndex + 2 ] = offset[2 ]
195
+
196
+ val colorIndex = i * COLOR_COMPONENT_SIZE
197
+ ringColorArray.forEachIndexed { index, value ->
198
+ positionsColor[colorIndex + index] = value
199
+ }
184
200
}
185
- return positions.toList() to colors.toList()
201
+
202
+ return Ring (positions, positionsColor)
203
+ }
204
+
205
+ private fun joinMultipleArrays (arrays : List <FloatArray >): FloatArray {
206
+ val result = FloatArray (arrays.sumOf { it.size })
207
+ var offset = 0
208
+ for (array in arrays) {
209
+ array.copyInto(result, offset)
210
+ offset + = array.size
211
+ }
212
+ return result
186
213
}
187
214
188
215
companion object {
189
216
private const val MARKER_TRANSLATE_Z_FACTOR = 1.0001f
190
217
}
191
218
}
219
+
220
+ data class Ring (val vertices : FloatArray , val verticesColor : FloatArray )
0 commit comments