bevy icon indicating copy to clipboard operation
bevy copied to clipboard

2D GLTF scene support

Open jpedrick opened this issue 1 year ago • 0 comments

What problem does this solve or what need does it fill?

I'm using blender to create a 2D scene using the "2D Animation" mode. When using an OrthographicCamera to view a scene loaded from a GLTF file all of the Meshes and Materials are 3D and are not rendered. Conversion into a 2D scene is fairly cumbersome.

What solution would you like?

I'd like a "Scene2dBundle" that best effort can display a gltf in an Orthographic view.

            Scene2dBundle{
                scene: my_gltf.scenes[0].clone(),
                ..default()
            }

What alternative(s) have you considered?

Currently, I am iterating over the nodes in the Gltf as follows:

            for gltf_node in my_gltf.nodes.iter() {
                if let Some(node) = gltf_nodes.get(gltf_node) {
                    if let Some(mesh_handle) = &node.mesh {
                        if let Some(mesh) = gltfs_meshes.get(mesh_handle) {
                            for primative in mesh.primitives.iter() {
                                let color_mat = if let Some(mat) = &primative.material {
                                    if let Some(standard_mat) = standard_materials.get(mat) {
                                        materials.add(ColorMaterial::from(standard_mat.base_color))
                                    }
                                    else {
                                        materials.add(ColorMaterial::from(Color::rgb(3.2, 2.3, 0.4)))
                                    }
                                }
                                else {
                                    materials.add(ColorMaterial::from(Color::rgb(3.2, 2.3, 0.4)))
                                };
                                commands.spawn((MaterialMesh2dBundle{
                                    mesh: primative.mesh.clone().into(),
                                    material: color_mat,
                                    transform: Transform{ 
                                        translation: node.transform.translation * 150.0, // + 0.1 * Vec3::Z * (ix as f32),
                                        rotation: Quat::from_axis_angle(Vec3::X,std::f32::consts::PI / 2.0),
                                        scale: 150.0 * Vec3::ONE,
                                    },
                                    ..Default::default()
                                }, SplashElement));
                            }
                        }
                    }
                }
            }

Additional context

Any other information you would like to add such as related previous work, screenshots, benchmarks, etc.

An example 2D gltf from a Blender 2D Animation(no cameras exported and material left out due to being binary).

{
	"asset":{
		"generator":"Khronos glTF Blender I/O v4.0.44",
		"version":"2.0"
	},
	"scene":0,
	"scenes":[
		{
			"name":"Scene",
			"nodes":[
				0
			]
		}
	],
	"nodes":[
		{
			"mesh":0,
			"name":"Circle",
			"rotation":[
				0.7071068286895752,
				0,
				0,
				0.7071068286895752
			]
		}
	],
	"animations":[
		{
			"channels":[
				{
					"sampler":0,
					"target":{
						"node":0,
						"path":"translation"
					}
				},
				{
					"sampler":1,
					"target":{
						"node":0,
						"path":"rotation"
					}
				},
				{
					"sampler":2,
					"target":{
						"node":0,
						"path":"scale"
					}
				}
			],
			"name":"CircleAction",
			"samplers":[
				{
					"input":4,
					"interpolation":"LINEAR",
					"output":5
				},
				{
					"input":4,
					"interpolation":"LINEAR",
					"output":6
				},
				{
					"input":4,
					"interpolation":"LINEAR",
					"output":7
				}
			]
		}
	],
	"materials":[
		{
			"doubleSided":true,
			"name":"Material",
			"pbrMetallicRoughness":{
				"baseColorFactor":[
					0.05711526423692703,
					0.7999998927116394,
					0.027054570615291595,
					1
				],
				"metallicFactor":0,
				"roughnessFactor":0.5
			}
		}
	],
	"meshes":[
		{
			"name":"Circle",
			"primitives":[
				{
					"attributes":{
						"POSITION":0,
						"NORMAL":1,
						"TEXCOORD_0":2
					},
					"indices":3,
					"material":0
				}
			]
		}
	],
	"accessors":[
		{
			"bufferView":0,
			"componentType":5126,
			"count":32,
			"max":[
				1,
				0,
				1
			],
			"min":[
				-1,
				0,
				-1
			],
			"type":"VEC3"
		},
		{
			"bufferView":1,
			"componentType":5126,
			"count":32,
			"type":"VEC3"
		},
		{
			"bufferView":2,
			"componentType":5126,
			"count":32,
			"type":"VEC2"
		},
		{
			"bufferView":3,
			"componentType":5123,
			"count":90,
			"type":"SCALAR"
		},
		{
			"bufferView":4,
			"componentType":5126,
			"count":1,
			"max":[
				0.041666666666666664
			],
			"min":[
				0.041666666666666664
			],
			"type":"SCALAR"
		},
		{
			"bufferView":5,
			"componentType":5126,
			"count":1,
			"type":"VEC3"
		},
		{
			"bufferView":6,
			"componentType":5126,
			"count":1,
			"type":"VEC4"
		},
		{
			"bufferView":7,
			"componentType":5126,
			"count":1,
			"type":"VEC3"
		}
	],
	"bufferViews":[
		{
			"buffer":0,
			"byteLength":384,
			"byteOffset":0,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":384,
			"byteOffset":384,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":256,
			"byteOffset":768,
			"target":34962
		},
		{
			"buffer":0,
			"byteLength":180,
			"byteOffset":1024,
			"target":34963
		},
		{
			"buffer":0,
			"byteLength":4,
			"byteOffset":1204
		},
		{
			"buffer":0,
			"byteLength":12,
			"byteOffset":1208
		},
		{
			"buffer":0,
			"byteLength":16,
			"byteOffset":1220
		},
		{
			"buffer":0,
			"byteLength":12,
			"byteOffset":1236
		}
	],
	"buffers":[
		{
			"byteLength":1248,
			"uri":"circle.bin"
		}
	]
}

jpedrick avatar Feb 10 '24 16:02 jpedrick