@aguacerowx/react-native 0.0.17 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -0
- package/aguacerowx-react-native.podspec +27 -9
- package/android/build.gradle +31 -7
- package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
- package/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
- package/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
- package/android/src/main/res/raw/fragment_shader.glsl +120 -66
- package/ios/GridRenderLayer.swift +113 -92
- package/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/commonjs/README.md +66 -0
- package/lib/commonjs/aguacerowx-react-native.podspec +27 -9
- package/lib/commonjs/android/build.gradle +31 -7
- package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
- package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
- package/lib/commonjs/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
- package/lib/commonjs/android/src/main/res/raw/fragment_shader.glsl +120 -66
- package/lib/commonjs/ios/GridRenderLayer.swift +113 -92
- package/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
- package/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
- package/lib/commonjs/package.json +9 -4
- package/lib/commonjs/scripts/compile-shaders.sh +27 -0
- package/lib/commonjs/src/GridRenderLayer.js +8 -0
- package/lib/commonjs/src/GridRenderLayer.js.map +1 -1
- package/lib/commonjs/src/WeatherLayerManager.js +5 -0
- package/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
- package/lib/module/README.md +66 -0
- package/lib/module/aguacerowx-react-native.podspec +27 -9
- package/lib/module/android/build.gradle +31 -7
- package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayer.java +17 -1
- package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderLayerView.java +5 -0
- package/lib/module/android/src/main/java/com/aguacerowx/reactnative/GridRenderManager.java +8 -0
- package/lib/module/android/src/main/res/raw/fragment_shader.glsl +120 -66
- package/lib/module/ios/GridRenderLayer.swift +113 -92
- package/lib/module/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/module/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/module/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/module/lib/commonjs/README.md +66 -0
- package/lib/module/lib/commonjs/aguacerowx-react-native.podspec +27 -9
- package/lib/module/lib/commonjs/android/build.gradle +31 -7
- package/lib/module/lib/commonjs/ios/GridRenderLayer.swift +113 -92
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-device.metallib +0 -0
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders-simulator.metallib +0 -0
- package/lib/module/lib/commonjs/ios/compiled-shaders/Shaders.metallib +0 -0
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
- package/lib/module/lib/commonjs/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
- package/lib/module/lib/commonjs/package.json +9 -4
- package/lib/module/lib/commonjs/scripts/compile-shaders.sh +27 -0
- package/lib/module/lib/commonjs/src/GridRenderLayer.js +8 -0
- package/lib/module/lib/commonjs/src/GridRenderLayer.js.map +1 -1
- package/lib/module/lib/commonjs/src/WeatherLayerManager.js +5 -0
- package/lib/module/lib/commonjs/src/WeatherLayerManager.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js +128 -68
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/AguaceroCore.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js +39 -12
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/default-colormaps.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js +38 -20
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/dictionaries.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/index.js +0 -6
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/dist/index.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/package.json +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js +28 -2
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/AguaceroCore.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js +35 -8
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/default-colormaps.js.map +1 -1
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js +38 -20
- package/lib/module/node_modules/@aguacerowx/javascript-sdk/src/dictionaries.js.map +1 -1
- package/lib/module/package.json +9 -4
- package/lib/module/scripts/compile-shaders.sh +27 -0
- package/lib/module/src/GridRenderLayer.js +8 -0
- package/lib/module/src/GridRenderLayer.js.map +1 -1
- package/lib/module/src/WeatherLayerManager.js +5 -0
- package/lib/module/src/WeatherLayerManager.js.map +1 -1
- package/lib/typescript/src/GridRenderLayer.d.ts.map +1 -1
- package/lib/typescript/src/WeatherLayerManager.d.ts.map +1 -1
- package/package.json +9 -4
- package/src/GridRenderLayer.js +13 -0
- package/src/WeatherLayerManager.js +7 -0
|
@@ -5,94 +5,148 @@ varying vec2 v_texCoord;
|
|
|
5
5
|
|
|
6
6
|
uniform sampler2D u_data_texture;
|
|
7
7
|
uniform sampler2D u_colormap_texture;
|
|
8
|
+
|
|
9
|
+
// Data parameters
|
|
8
10
|
uniform float u_scale;
|
|
9
11
|
uniform float u_offset;
|
|
10
12
|
uniform float u_missing_quantized;
|
|
13
|
+
uniform int u_scale_type; // 0 for linear, 1 for sqrt
|
|
14
|
+
|
|
15
|
+
// Style parameters
|
|
11
16
|
uniform float u_opacity;
|
|
12
17
|
uniform vec2 u_data_range;
|
|
18
|
+
|
|
19
|
+
// Rendering parameters
|
|
13
20
|
uniform vec2 u_texture_size;
|
|
14
21
|
uniform int u_smoothing;
|
|
22
|
+
uniform int u_is_ptype; // ADDED: Flag for ptype variables
|
|
15
23
|
|
|
16
|
-
// ---
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
vec2 pixel_floor = floor(pixel_coord - 0.5) + 0.5;
|
|
27
|
-
vec2 f = pixel_coord - pixel_floor;
|
|
28
|
-
|
|
29
|
-
// Sample the 2x2 grid
|
|
30
|
-
float s00 = texture2D(u_data_texture, (pixel_floor + vec2(0.0, 0.0)) / u_texture_size).a * 255.0;
|
|
31
|
-
float s10 = texture2D(u_data_texture, (pixel_floor + vec2(1.0, 0.0)) / u_texture_size).a * 255.0;
|
|
32
|
-
float s01 = texture2D(u_data_texture, (pixel_floor + vec2(0.0, 1.0)) / u_texture_size).a * 255.0;
|
|
33
|
-
float s11 = texture2D(u_data_texture, (pixel_floor + vec2(1.0, 1.0)) / u_texture_size).a * 255.0;
|
|
34
|
-
|
|
35
|
-
// Check which samples are valid (not NaN)
|
|
36
|
-
bool valid00 = abs(s00 - missing_in_texture_range) >= 0.5;
|
|
37
|
-
bool valid10 = abs(s10 - missing_in_texture_range) >= 0.5;
|
|
38
|
-
bool valid01 = abs(s01 - missing_in_texture_range) >= 0.5;
|
|
39
|
-
bool valid11 = abs(s11 - missing_in_texture_range) >= 0.5;
|
|
40
|
-
|
|
41
|
-
// If ANY sample is NaN, return NaN (this pixel is on an edge)
|
|
42
|
-
if (!valid00 || !valid10 || !valid01 || !valid11) {
|
|
43
|
-
return missing_in_texture_range;
|
|
24
|
+
// --- HELPER FUNCTIONS ---
|
|
25
|
+
|
|
26
|
+
// Dequantizes a signed value (-127 to 127) into a physical value
|
|
27
|
+
float dequantize_val(float q_val) {
|
|
28
|
+
if (abs(q_val - u_missing_quantized) < 0.5) {
|
|
29
|
+
return -9999.0;
|
|
30
|
+
}
|
|
31
|
+
float intermediate = q_val * u_scale + u_offset;
|
|
32
|
+
if (u_scale_type == 1) { // 1 = sqrt
|
|
33
|
+
return intermediate * abs(intermediate);
|
|
44
34
|
}
|
|
35
|
+
return intermediate;
|
|
36
|
+
}
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
// Samples texture, converts 0-255 to signed -128-127 range.
|
|
39
|
+
// Returns a quantized value, or a large positive sentinel for missing data.
|
|
40
|
+
float get_value(vec2 coord) {
|
|
41
|
+
float value_0_to_255 = texture2D(u_data_texture, coord).a * 255.0;
|
|
42
|
+
float val = value_0_to_255 - 128.0;
|
|
43
|
+
float missing_in_texture_range_0_255 = u_missing_quantized + 128.0;
|
|
44
|
+
if (abs(value_0_to_255 - missing_in_texture_range_0_255) < 0.5) {
|
|
45
|
+
return 99999.0; // Sentinel for "missing"
|
|
46
|
+
}
|
|
47
|
+
return val;
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
//
|
|
53
|
-
float
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
// Maps a physical value to a precipitation type category
|
|
51
|
+
float get_ptype_from_physical(float val) {
|
|
52
|
+
if (val < 0.0) return -1.0; // Missing/Invalid
|
|
53
|
+
if (val < 100.0) return 0.0; // Rain
|
|
54
|
+
if (val < 200.0) return 1.0; // Mix
|
|
55
|
+
if (val < 300.0) return 2.0; // Snow
|
|
56
|
+
return 3.0; // Pellets
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
|
|
59
60
|
void main() {
|
|
60
|
-
|
|
61
|
-
float
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
float raw_value;
|
|
62
|
+
float total_weight = 1.0; // Used for alpha feathering at data edges
|
|
63
|
+
|
|
64
|
+
if (u_smoothing == 0) { // Nearest neighbor
|
|
65
|
+
float quantized_value = get_value(v_texCoord);
|
|
66
|
+
if (quantized_value >= 99999.0) {
|
|
67
|
+
discard;
|
|
68
|
+
}
|
|
69
|
+
raw_value = dequantize_val(quantized_value);
|
|
70
|
+
|
|
71
|
+
} else { // Bilinear interpolation
|
|
72
|
+
vec2 texel_size = 1.0 / u_texture_size;
|
|
73
|
+
vec2 tex_coord_in_texels = v_texCoord * u_texture_size;
|
|
74
|
+
vec2 bl_texel_index = floor(tex_coord_in_texels - 0.5);
|
|
75
|
+
vec2 f = fract(tex_coord_in_texels - 0.5); // Interpolation factors
|
|
76
|
+
|
|
77
|
+
// Coordinates of the 4 neighboring texels
|
|
78
|
+
vec2 v00_coord = (bl_texel_index + vec2(0.5, 0.5)) * texel_size;
|
|
79
|
+
vec2 v10_coord = (bl_texel_index + vec2(1.5, 0.5)) * texel_size;
|
|
80
|
+
vec2 v01_coord = (bl_texel_index + vec2(0.5, 1.5)) * texel_size;
|
|
81
|
+
vec2 v11_coord = (bl_texel_index + vec2(1.5, 1.5)) * texel_size;
|
|
82
|
+
|
|
83
|
+
if (u_is_ptype == 1) {
|
|
84
|
+
// --- PTYPE-SPECIFIC INTERPOLATION ---
|
|
85
|
+
float v00 = dequantize_val(get_value(v00_coord));
|
|
86
|
+
float v10 = dequantize_val(get_value(v10_coord));
|
|
87
|
+
float v01 = dequantize_val(get_value(v01_coord));
|
|
88
|
+
float v11 = dequantize_val(get_value(v11_coord));
|
|
89
|
+
|
|
90
|
+
float p00 = get_ptype_from_physical(v00);
|
|
91
|
+
float p10 = get_ptype_from_physical(v10);
|
|
92
|
+
float p01 = get_ptype_from_physical(v01);
|
|
93
|
+
float p11 = get_ptype_from_physical(v11);
|
|
94
|
+
|
|
95
|
+
// Determine the dominant precipitation type for this pixel
|
|
96
|
+
float dominant_ptype = -1.0;
|
|
97
|
+
if (p00 != -1.0) dominant_ptype = p00;
|
|
98
|
+
else if (p10 != -1.0) dominant_ptype = p10;
|
|
99
|
+
else if (p01 != -1.0) dominant_ptype = p01;
|
|
100
|
+
else if (p11 != -1.0) dominant_ptype = p11;
|
|
101
|
+
|
|
102
|
+
if (dominant_ptype == -1.0) discard;
|
|
103
|
+
|
|
104
|
+
// Interpolate ONLY the values that match the dominant ptype
|
|
105
|
+
float total_value = 0.0;
|
|
106
|
+
total_weight = 0.0;
|
|
107
|
+
if (p00 == dominant_ptype) { float w = (1.0-f.x)*(1.0-f.y); total_value+=v00*w; total_weight+=w; }
|
|
108
|
+
if (p10 == dominant_ptype) { float w = f.x*(1.0-f.y); total_value+=v10*w; total_weight+=w; }
|
|
109
|
+
if (p01 == dominant_ptype) { float w = (1.0-f.x)*f.y; total_value+=v01*w; total_weight+=w; }
|
|
110
|
+
if (p11 == dominant_ptype) { float w = f.x*f.y; total_value+=v11*w; total_weight+=w; }
|
|
111
|
+
|
|
112
|
+
if (total_weight <= 0.0) discard;
|
|
113
|
+
raw_value = total_value / total_weight;
|
|
114
|
+
|
|
115
|
+
// Force full alpha to prevent dark borders between ptype regions
|
|
116
|
+
total_weight = 1.0;
|
|
117
|
+
|
|
118
|
+
} else {
|
|
119
|
+
// --- STANDARD INTERPOLATION ---
|
|
120
|
+
float v00_q = get_value(v00_coord);
|
|
121
|
+
float v10_q = get_value(v10_coord);
|
|
122
|
+
float v01_q = get_value(v01_coord);
|
|
123
|
+
float v11_q = get_value(v11_coord);
|
|
124
|
+
|
|
125
|
+
float total_value_q = 0.0;
|
|
126
|
+
total_weight = 0.0;
|
|
127
|
+
if (v00_q < 99999.0) { float w = (1.0-f.x)*(1.0-f.y); total_value_q+=v00_q*w; total_weight+=w; }
|
|
128
|
+
if (v10_q < 99999.0) { float w = f.x*(1.0-f.y); total_value_q+=v10_q*w; total_weight+=w; }
|
|
129
|
+
if (v01_q < 99999.0) { float w = (1.0-f.x)*f.y; total_value_q+=v01_q*w; total_weight+=w; }
|
|
130
|
+
if (v11_q < 99999.0) { float w = f.x*f.y; total_value_q+=v11_q*w; total_weight+=w; }
|
|
131
|
+
|
|
132
|
+
if (total_weight <= 0.0) discard;
|
|
133
|
+
raw_value = dequantize_val(total_value_q / total_weight);
|
|
134
|
+
}
|
|
66
135
|
}
|
|
67
136
|
|
|
68
|
-
|
|
137
|
+
// --- COMMON FINAL STEPS ---
|
|
69
138
|
|
|
70
|
-
|
|
71
|
-
if (abs(value_in_texture - missing_in_texture_range) < 0.5) {
|
|
139
|
+
if (raw_value < u_data_range.x) {
|
|
72
140
|
discard;
|
|
73
141
|
}
|
|
74
142
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Step 2: Apply non-linear inverse scaling if specified
|
|
81
|
-
if (u_scale_type == 1) { // 1 represents 'sqrt'
|
|
82
|
-
// Square the intermediate value while preserving its sign
|
|
83
|
-
raw_value = intermediate_value * abs(intermediate_value);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// If the data is below the specified minimum range, make it invisible.
|
|
87
|
-
if (raw_value < u_data_range.x) {
|
|
143
|
+
float colormap_coord = clamp((raw_value - u_data_range.x) / (u_data_range.y - u_data_range.x), 0.0, 1.0);
|
|
144
|
+
vec4 color = texture2D(u_colormap_texture, vec2(colormap_coord, 0.5));
|
|
145
|
+
|
|
146
|
+
if (color.a < 0.1) {
|
|
88
147
|
discard;
|
|
89
148
|
}
|
|
90
149
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
colormap_coord = clamp(colormap_coord, 0.0, 1.0);
|
|
94
|
-
|
|
95
|
-
// Sample the colormap and apply opacity
|
|
96
|
-
vec4 color = texture2D(u_colormap_texture, vec2(colormap_coord, 0.5));
|
|
97
|
-
gl_FragColor = vec4(color.rgb, color.a * u_opacity);
|
|
150
|
+
float final_alpha = color.a * u_opacity * total_weight;
|
|
151
|
+
gl_FragColor = vec4(color.rgb * final_alpha, final_alpha);
|
|
98
152
|
}
|
|
@@ -783,99 +783,120 @@ public class GridRenderLayer: NSObject {
|
|
|
783
783
|
|
|
784
784
|
// MARK: - Internal methods for CustomLayerHost (called by wrapper)
|
|
785
785
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
if let pendingColormap = pendingColormapUpdate {
|
|
866
|
-
print("🟡 [GridRenderLayer] Processing pending colormap update")
|
|
867
|
-
updateColormapTexture(colormapAsBase64: pendingColormap)
|
|
868
|
-
pendingColormapUpdate = nil
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
if let pendingData = pendingDataUpdate {
|
|
872
|
-
print("🟡 [GridRenderLayer] Processing pending data update")
|
|
873
|
-
updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
|
|
874
|
-
scale: pendingData.scale, offset: pendingData.offset,
|
|
875
|
-
missing: pendingData.missing, scaleType: pendingData.scaleType)
|
|
876
|
-
pendingDataUpdate = nil
|
|
877
|
-
}
|
|
786
|
+
internal func internalRenderingWillStart(_ metalDevice: MTLDevice, colorPixelFormat: UInt, depthStencilPixelFormat: UInt) {
|
|
787
|
+
print("🟢 [GridRenderLayer] renderingWillStart called")
|
|
788
|
+
self.device = metalDevice
|
|
789
|
+
self.commandQueue = metalDevice.makeCommandQueue()
|
|
790
|
+
|
|
791
|
+
let bundle = Bundle(for: GridRenderLayer.self)
|
|
792
|
+
|
|
793
|
+
// Determine if we're running on simulator or device
|
|
794
|
+
#if targetEnvironment(simulator)
|
|
795
|
+
let metallibName = "Shaders-simulator"
|
|
796
|
+
#else
|
|
797
|
+
let metallibName = "Shaders-device"
|
|
798
|
+
#endif
|
|
799
|
+
|
|
800
|
+
// Try to load pre-compiled metallib for the current platform
|
|
801
|
+
let defaultLibrary: MTLLibrary?
|
|
802
|
+
if let metallibUrl = bundle.url(forResource: metallibName, withExtension: "metallib"),
|
|
803
|
+
let library = try? metalDevice.makeLibrary(URL: metallibUrl) {
|
|
804
|
+
print("✅ [GridRenderLayer] Loaded pre-compiled metallib (\(metallibName))")
|
|
805
|
+
defaultLibrary = library
|
|
806
|
+
}
|
|
807
|
+
// Fall back to compiling from .metal source (for development with npm link)
|
|
808
|
+
else if let metalUrl = bundle.url(forResource: "Shaders", withExtension: "metal"),
|
|
809
|
+
let source = try? String(contentsOf: metalUrl),
|
|
810
|
+
let library = try? metalDevice.makeLibrary(source: source, options: nil) {
|
|
811
|
+
print("✅ [GridRenderLayer] Compiled Metal shader from source")
|
|
812
|
+
defaultLibrary = library
|
|
813
|
+
}
|
|
814
|
+
// Neither worked
|
|
815
|
+
else {
|
|
816
|
+
print("❌ [GridRenderLayer] Could not find or compile Metal shaders")
|
|
817
|
+
print(" Bundle path: \(bundle.bundlePath)")
|
|
818
|
+
return
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
guard let library = defaultLibrary else {
|
|
822
|
+
print("❌ [GridRenderLayer] Failed to create Metal library")
|
|
823
|
+
return
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
let vertexFunction = library.makeFunction(name: "vertex_main")
|
|
827
|
+
let fragmentFunction = library.makeFunction(name: "fragment_main")
|
|
828
|
+
|
|
829
|
+
// Set up vertex descriptor
|
|
830
|
+
let vertexDescriptor = MTLVertexDescriptor()
|
|
831
|
+
vertexDescriptor.attributes[0].format = .float2 // position (x, y)
|
|
832
|
+
vertexDescriptor.attributes[0].offset = 0
|
|
833
|
+
vertexDescriptor.attributes[0].bufferIndex = 0
|
|
834
|
+
|
|
835
|
+
vertexDescriptor.attributes[1].format = .float2 // texCoord (u, v)
|
|
836
|
+
vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.size * 2
|
|
837
|
+
vertexDescriptor.attributes[1].bufferIndex = 0
|
|
838
|
+
|
|
839
|
+
vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.size * 4 // 2 floats for pos + 2 for texCoord
|
|
840
|
+
vertexDescriptor.layouts[0].stepFunction = .perVertex
|
|
841
|
+
|
|
842
|
+
let pipelineDescriptor = MTLRenderPipelineDescriptor()
|
|
843
|
+
pipelineDescriptor.vertexDescriptor = vertexDescriptor
|
|
844
|
+
pipelineDescriptor.vertexFunction = vertexFunction
|
|
845
|
+
pipelineDescriptor.fragmentFunction = fragmentFunction
|
|
846
|
+
|
|
847
|
+
pipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat(rawValue: colorPixelFormat) ?? .bgra8Unorm
|
|
848
|
+
pipelineDescriptor.depthAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
|
|
849
|
+
pipelineDescriptor.stencilAttachmentPixelFormat = MTLPixelFormat(rawValue: depthStencilPixelFormat) ?? .depth32Float_stencil8
|
|
850
|
+
|
|
851
|
+
pipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
|
|
852
|
+
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
|
|
853
|
+
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = .add
|
|
854
|
+
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
|
|
855
|
+
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
|
|
856
|
+
pipelineDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
|
|
857
|
+
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
|
|
858
|
+
|
|
859
|
+
do {
|
|
860
|
+
self.pipelineState = try metalDevice.makeRenderPipelineState(descriptor: pipelineDescriptor)
|
|
861
|
+
} catch {
|
|
862
|
+
print("❌ [GridRenderLayer] Failed to create pipeline state: \(error)")
|
|
863
|
+
return
|
|
878
864
|
}
|
|
865
|
+
|
|
866
|
+
let dataSamplerDesc = MTLSamplerDescriptor()
|
|
867
|
+
dataSamplerDesc.minFilter = .nearest
|
|
868
|
+
dataSamplerDesc.magFilter = .nearest
|
|
869
|
+
self.dataSamplerState = metalDevice.makeSamplerState(descriptor: dataSamplerDesc)
|
|
870
|
+
|
|
871
|
+
let colormapSamplerDesc = MTLSamplerDescriptor()
|
|
872
|
+
colormapSamplerDesc.minFilter = .nearest
|
|
873
|
+
colormapSamplerDesc.magFilter = .nearest
|
|
874
|
+
colormapSamplerDesc.sAddressMode = .clampToEdge
|
|
875
|
+
self.colormapSamplerState = metalDevice.makeSamplerState(descriptor: colormapSamplerDesc)
|
|
876
|
+
|
|
877
|
+
print("🟢 [GridRenderLayer] Metal setup complete")
|
|
878
|
+
|
|
879
|
+
// Process any pending updates that came in before Metal was ready
|
|
880
|
+
if let pendingGeometry = pendingGeometryUpdate {
|
|
881
|
+
print("🟡 [GridRenderLayer] Processing pending geometry update")
|
|
882
|
+
updateGeometry(corners: pendingGeometry.corners, gridDef: pendingGeometry.gridDef)
|
|
883
|
+
pendingGeometryUpdate = nil
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
if let pendingColormap = pendingColormapUpdate {
|
|
887
|
+
print("🟡 [GridRenderLayer] Processing pending colormap update")
|
|
888
|
+
updateColormapTexture(colormapAsBase64: pendingColormap)
|
|
889
|
+
pendingColormapUpdate = nil
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
if let pendingData = pendingDataUpdate {
|
|
893
|
+
print("🟡 [GridRenderLayer] Processing pending data update")
|
|
894
|
+
updateDataTexture(data: pendingData.data, nx: pendingData.nx, ny: pendingData.ny,
|
|
895
|
+
scale: pendingData.scale, offset: pendingData.offset,
|
|
896
|
+
missing: pendingData.missing, scaleType: pendingData.scaleType)
|
|
897
|
+
pendingDataUpdate = nil
|
|
898
|
+
}
|
|
899
|
+
}
|
|
879
900
|
internal func internalRender(_ parameters: CustomLayerRenderParameters, mtlCommandBuffer: MTLCommandBuffer, mtlRenderPassDescriptor: MTLRenderPassDescriptor) {
|
|
880
901
|
guard isVisible,
|
|
881
902
|
let pipeline = pipelineState,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|