nx_nxa_morf_draw_admit.nx source
↩ module page · 78 lines · 4290 B
1// ORIGINAL. Compose the canonical MORF ingress with existing geometric normals.
2// Internal borrowed view only: no allocation, parsing duplicate, memory growth,
3// public pointer API, expression policy or geometry upload.
4import "nx_nxa_morf_admit.nx"
5import "nx_morf_draw_core.nx"
6const NMD_E_TRIANGLES: i64 = 0-941
7const NMD_E_ALIAS: i64 = 0-942
8const NMD_E_NORMAL_WORDS: i64 = 0-943
9
10func nmd_admit(b: *u8,flen: i64,member: *u8,member_bytes: i64,morph: *NmiAsset,normals: *i64,normal_words: i64,draw: *MrdAsset) -> i64 {
11 // Morph view may publish success even if later topology admission refuses;
12 // the caller may consume draw ONLY on this function's zero return.
13 let rc: i64 = nmi_admit(b,flen,member,member_bytes,morph)
14 if rc < 0 { return rc }
15 let v: *MvcView = morph.view
16 if normal_words != v.bind_words { return NMD_E_NORMAL_WORDS }
17 if mvc_span(normals,normal_words) == 0 { return NMD_E_NORMAL_WORDS }
18 if mvc_span(draw as *i64,__size_of(MrdAsset)/MVC_WORD) == 0 { return NMD_E_ALIAS }
19 if nmi_byte_overlap(normals as *u8,normal_words*MVC_WORD,b,flen) != 0 { return NMD_E_ALIAS }
20 if nmi_byte_overlap(normals as *u8,normal_words*MVC_WORD,member,member_bytes) != 0 { return NMD_E_ALIAS }
21 if mvc_overlap(normals,normal_words,morph as *i64,__size_of(NmiAsset)/MVC_WORD) != 0 { return NMD_E_ALIAS }
22 if mvc_overlap(normals,normal_words,v as *i64,__size_of(MvcView)/MVC_WORD) != 0 { return NMD_E_ALIAS }
23 if mvc_overlap(normals,normal_words,draw as *i64,__size_of(MrdAsset)/MVC_WORD) != 0 { return NMD_E_ALIAS }
24 if nmi_byte_overlap(draw as *u8,__size_of(MrdAsset),b,flen) != 0 { return NMD_E_ALIAS }
25 if nmi_byte_overlap(draw as *u8,__size_of(MrdAsset),member,member_bytes) != 0 { return NMD_E_ALIAS }
26 if mvc_overlap(draw as *i64,__size_of(MrdAsset)/MVC_WORD,morph as *i64,__size_of(NmiAsset)/MVC_WORD) != 0 { return NMD_E_ALIAS }
27 if mvc_overlap(draw as *i64,__size_of(MrdAsset)/MVC_WORD,v as *i64,__size_of(MvcView)/MVC_WORD) != 0 { return NMD_E_ALIAS }
28 let tag: i64 = nxa_tag4("TRIS" as *u8)
29 let entry: i64 = nxa_section_entry(b,flen,tag)
30 let offset: i64 = nxa_counted_section(b,flen,tag,VN_TRI_I)
31 if entry < 0 { return NMD_E_TRIANGLES }; if offset < 0 { return NMD_E_TRIANGLES }
32 let h: *i64 = b as *i64
33 var count: i64 = 0; var s: i64 = 0
34 while s < h[2] { if h[4+s*4] == tag { count = count+1 }; s = s+1 }
35 if count != 1 { return NMD_E_TRIANGLES }
36 // A checksummed section may still alias another checksummed section. The
37 // canonical MORF reader already validates its own three-way separation.
38 let payload: *i64 = ((b as i64)+h[entry+1]) as *i64
39 let payload_words: i64 = h[entry+2]
40 let vt: i64 = nxa_tag4("VERT" as *u8)
41 let ft: i64 = nxa_tag4("FACE" as *u8)
42 let mt: i64 = nxa_tag4("MORF" as *u8)
43 s = 0
44 while s < h[2] {
45 let e: i64 = 4+s*4; let tg: i64 = h[e]; var target: i64 = 0
46 if tg == vt { target = 1 }; if tg == ft { target = 1 }; if tg == mt { target = 1 }
47 if target == 1 {
48 let other: *i64 = ((b as i64)+h[e+1]) as *i64
49 if mvc_overlap(payload,payload_words,other,h[e+2]) != 0 { return NMD_E_ALIAS }
50 }
51 s = s+1
52 }
53 let nt: i64 = h[offset]
54 let triangles: *i64 = ((b as i64)+(offset+1)*MVC_WORD) as *i64
55 let triangle_words: i64 = payload_words-1
56 var i: i64 = 0
57 // All indices are checked before any baseline-normal scratch is written.
58 while i < triangle_words {
59 if triangles[i] < 0 { return NMD_E_TRIANGLES }
60 if triangles[i] >= v.vertices { return NMD_E_TRIANGLES }
61 i = i+1
62 }
63 i = 0
64 while i < v.vertices { normals[i] = 0; i = i+1 }
65 var degree: i64 = 0; i = 0
66 while i < triangle_words {
67 let id: i64 = triangles[i]
68 normals[id] = normals[id]+1
69 if normals[id] > degree { degree = normals[id] }; i = i+1
70 }
71 let envelope: i64 = mrd_normal_envelope(v.bind,triangles,nt,degree)
72 if envelope < 0 { return envelope }
73 let smooth: i64 = vn_smooth_area(v.bind,triangles,v.vertices,nt,normals)
74 if smooth < 0 { return smooth }
75 draw.morph = v; draw.triangles = triangles; draw.triangle_words = triangle_words
76 draw.bind_normals = normals; draw.normal_words = normal_words
77 return 0
78}