Skip to content

Commit 13adace

Browse files
committed
feat(cursor): recut the Prism Glow 3D hand as a gem after the new sheet
The crystal hand was still the old faceted glove (capsule fingers, a long index). It is now six convex gems on one slab, after 3d-concept.png: an index column with a cut tip, three fingers side by side, the thumb and a triangulated palm, the fingers standing over the palm so their crease is the knuckle line. Both Prism Glow models are now plane tables (the arrow keeps its exact cut), written into the three shaders by scripts/generate-prism-glow-gem.mjs; a test checks the three tables agree. The crystal glows on its own, facets take deeper cyan, blue and violet tones from their orientation, and sharp edges light up (s_gem_glint). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019NRvCeDSc9MDhL3yrfQwZK
1 parent 9b36606 commit 13adace

7 files changed

Lines changed: 865 additions & 251 deletions

File tree

‎crates/compositor/src/sculpt.rs‎

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ const Z_HIGH_ARROW: f32 = 0.31;
3030
const Z_HIGH_HAND: f32 = 0.4;
3131
/// Boîtes des modèles dans le prototype (x0, x1, haut). Leur hauteur est celle du sprite,
3232
/// 1 / SCULPT_SCALE : le mode 15 tient le plus grand côté de la boîte pour 1 (`sprite_size`).
33-
/// Celles du cristal et des voxels ; puis les thèmes cerclés, que leur trait élargit et que
34-
/// débordent l'étoile et les feuilles (Star Sprout), les tirets du clic et le calque jaune (Pop
35-
/// Coral), le pouce.
33+
/// Celles de la flèche taillée et des voxels, puis de la main taillée, dont le pouce déborde ;
34+
/// puis les thèmes cerclés, que leur trait élargit et que débordent l'étoile et les feuilles (Star
35+
/// Sprout), les tirets du clic et le calque jaune (Pop Coral), le pouce.
3636
const BOX_ARROW: [f32; 3] = [-0.1, 0.75, 0.09];
3737
const BOX_HAND: [f32; 3] = [-0.27, 0.73, 0.07];
38+
const BOX_GEM_HAND: [f32; 3] = [-0.39, 0.61, 0.03];
3839
const BOX_INK_ARROW: [f32; 3] = [-0.08, 0.6, 0.03];
3940
const BOX_INK_HAND: [f32; 3] = [-0.36, 0.6, 0.03];
4041
const BOX_CORAL_ARROW: [f32; 3] = [-0.35, 0.6, 0.06];
@@ -61,6 +62,7 @@ fn silhouette_top(theme: usize, arrow: bool) -> f32 {
6162
/// La boîte du modèle (x0, x1, haut) dans le prototype.
6263
fn model_box(theme: usize, arrow: bool) -> [f32; 3] {
6364
match (THEMES[theme], arrow) {
65+
("prism-glow", false) => BOX_GEM_HAND,
6466
("studio-ink", true) => BOX_INK_ARROW,
6567
("studio-ink", false) => BOX_INK_HAND,
6668
("pop-coral", true) => BOX_CORAL_ARROW,
@@ -170,4 +172,43 @@ mod tests {
170172
}
171173
}
172174
}
175+
176+
/// Les plans taillés de Prism Glow, que `scripts/generate-prism-glow-gem.mjs` écrit dans les
177+
/// trois shaders, y sont les mêmes ; chaque pièce a ses plans et leurs normales sont unitaires.
178+
#[test]
179+
fn the_gem_tables_match_in_the_three_shaders() {
180+
let tables = [
181+
include_str!("shaders.hlsl"),
182+
include_str!("shaders.metal"),
183+
include_str!("vk_shaders/layer.wgsl"),
184+
]
185+
.map(|src| {
186+
let a = src.find("// <prism-glow-gem>").expect("marqueur d'ouverture");
187+
let b = src.find("// </prism-glow-gem>").expect("marqueur de fermeture");
188+
let block = &src[a..b];
189+
let decimals: Vec<f32> = block
190+
.split(|c: char| !(c.is_ascii_digit() || c == '.' || c == '-'))
191+
.filter(|t| t.contains('.'))
192+
.map(|t| t.parse().unwrap())
193+
.collect();
194+
let line = block.lines().find(|l| l.contains("GEM_PIECE")).unwrap();
195+
let list = &line[line.rfind(['(', '{']).unwrap() + 1..];
196+
let starts: Vec<usize> = list
197+
.split(|c: char| !c.is_ascii_digit())
198+
.filter(|t| !t.is_empty())
199+
.map(|t| t.parse().unwrap())
200+
.collect();
201+
(decimals, starts)
202+
});
203+
let (decimals, starts) = &tables[0];
204+
assert!(tables.iter().all(|t| t == &tables[0]), "tables différentes d'un shader à l'autre");
205+
assert_eq!(starts.len(), 9, "2 pièces de flèche, 6 de main");
206+
assert!(starts.windows(2).all(|w| w[1] >= w[0] + 4), "une pièce sans volume");
207+
let planes = starts[8];
208+
assert_eq!(decimals.len(), planes * 4 + 4 * 3, "plans puis boîtes");
209+
for p in decimals[..planes * 4].chunks(4) {
210+
let len = (p[0] * p[0] + p[1] * p[1] + p[2] * p[2]).sqrt();
211+
assert!((len - 1.0).abs() < 1e-3, "normale non unitaire : {p:?}");
212+
}
213+
}
173214
}

0 commit comments

Comments
 (0)