code wiki / (root) / nx_nxa_morf_draw_admit.nx

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}