MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / parse_primitive

Function parse_primitive

native/watchos/src/models.rs:361–438  ·  view source on GitHub ↗
(
    prim: &JVal, root: &JVal,
    accessors: &[JVal], buf_views: &[JVal], bin_bytes: &[u8],
)

Source from the content-addressed store, hash-verified

359}
360
361fn parse_primitive(
362 prim: &JVal, root: &JVal,
363 accessors: &[JVal], buf_views: &[JVal], bin_bytes: &[u8],
364) -> Option<Primitive> {
365 let attrs = prim.get("attributes")?;
366 let pos_acc = attrs.get("POSITION")?.num()? as usize;
367 let nrm_acc = attrs.get("NORMAL").and_then(|v| v.num().map(|n| n as usize));
368 let uv_acc = attrs.get("TEXCOORD_0").and_then(|v| v.num().map(|n| n as usize));
369 let j0_acc = attrs.get("JOINTS_0").and_then(|v| v.num().map(|n| n as usize));
370 let w0_acc = attrs.get("WEIGHTS_0").and_then(|v| v.num().map(|n| n as usize));
371 let idx_acc = prim.get("indices").and_then(|v| v.num().map(|n| n as usize));
372 let mat_idx = prim.get("material").and_then(|v| v.num().map(|n| n as usize));
373
374 let positions = read_f32_vec(accessors, buf_views, bin_bytes, pos_acc, 3)?;
375 let normals = nrm_acc
376 .and_then(|a| read_f32_vec(accessors, buf_views, bin_bytes, a, 3))
377 .unwrap_or_default();
378 let uvs = uv_acc
379 .and_then(|a| read_f32_vec(accessors, buf_views, bin_bytes, a, 2))
380 .unwrap_or_default();
381 // Indexless primitives (POSITION-only triangle soups) — synthesize
382 // sequential indices so the SceneKit SCNGeometryElement path stays
383 // uniform. Fox.glb uses this layout.
384 let indices = match idx_acc {
385 Some(a) => read_index_vec(accessors, buf_views, bin_bytes, a)?,
386 None => (0..(positions.len() / 3) as u32).collect(),
387 };
388 // JOINTS_0 is typically unsigned byte or short vec4 per vertex.
389 let joint_indices = j0_acc
390 .and_then(|a| read_joint_indices(accessors, buf_views, bin_bytes, a))
391 .unwrap_or_default();
392 // WEIGHTS_0 is f32 vec4 per vertex (spec allows normalized u8/u16 but
393 // current Khronos samples use float; stick with float for v1).
394 let weights = w0_acc
395 .and_then(|a| read_f32_vec(accessors, buf_views, bin_bytes, a, 4))
396 .unwrap_or_default();
397
398 let mut color = [1.0f32; 4];
399 let mut metallic = 1.0f32;
400 let mut roughness = 1.0f32;
401 let mut tex_base_color = 0u32;
402 let mut tex_normal = 0u32;
403 let mut tex_metallic_roughness = 0u32;
404 let mut tex_emissive = 0u32;
405 let mut tex_occlusion = 0u32;
406
407 if let Some(mi) = mat_idx {
408 if let Some(mats) = root.get("materials").and_then(|v| v.arr()) {
409 if let Some(mat) = mats.get(mi) {
410 if let Some(pbr) = mat.get("pbrMetallicRoughness") {
411 if let Some(bc) = pbr.get("baseColorFactor").and_then(|v| v.arr()) {
412 for (i, n) in bc.iter().take(4).enumerate() {
413 if let Some(f) = n.num() { color[i] = f as f32; }
414 }
415 }
416 if let Some(m) = pbr.get("metallicFactor").and_then(|v| v.num()) {
417 metallic = m as f32;
418 }

Callers 1

parse_glbFunction · 0.85

Calls 8

read_f32_vecFunction · 0.85
read_index_vecFunction · 0.85
read_joint_indicesFunction · 0.85
resolve_textureFunction · 0.85
numMethod · 0.80
arrMethod · 0.80
iterMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected