from pathlib import Path from ursina import application from time import perf_counter from ursina.string_utilities import print_info def ursinamesh_to_obj(mesh, name='', out_path=application.compressed_models_folder, max_decimals=5, flip_faces=True): from ursina.string_utilities import camel_to_snake obj = '' obj += f'mtllib {name}.mtl\n' obj += f'usemtl {name}\n' if not name: name = camel_to_snake(mesh.__class__.__name__) obj += 'o ' + name + '\n' verts = mesh.vertices for v in verts: v = [round(e, max_decimals) for e in v] obj += f'v {v[0]} {v[1]} {v[2]}\n' if mesh.uvs: for uv in mesh.uvs: uv = [round(e, max_decimals) for e in uv] obj += f'vt {uv[0]} {uv[1]}\n' obj += 's off\n' if mesh.triangles: tris = mesh.triangles if isinstance(tris[0], tuple): # convert from tuples to flat new_tris = [] for t in tris: if len(t) == 3: if not flip_faces: new_tris.extend([t[0], t[1], t[2]]) else: new_tris.extend([t[2], t[1], t[0]]) elif len(t) == 4: # turn quad into tris if not flip_faces: new_tris.extend([t[0], t[1], t[2], t[2], t[3], t[0]]) else: new_tris.extend([t[2], t[1], t[0], t[0], t[3], t[2]]) tris = new_tris if mesh.mode == 'ngon': tris = [] for i in range(1, len(mesh.vertices)-1): tris.extend((i, i+1, 0)) # tris must be a list of indices for i, t in enumerate(tris): if i % 3 == 0: obj += '\nf ' obj += str(t+1) if mesh.uvs: obj += '/'+str(t+1) obj += ' ' obj += '\n' # print(obj) with open(out_path / (name + '.obj'), 'w') as f: f.write(obj) print_info('saved obj:', out_path / (name + '.obj')) def ursinamesh_to_dae(mesh, name, folder:Path=application.compressed_models_folder, texture_name=''): num_vertices = len(mesh.generated_vertices) vertices = ' '.join([f'{v[2]} {v[1]} {v[0]}' for v in mesh.generated_vertices]) # triangle_indices = ' '.join([f'{i} '*4 for i in range(num_vertices, 0, -1)]) triangle_indices = ' '.join([f'{i} '*4 for i in range(num_vertices)]) num_triangle_indices = num_vertices num_uvs = len(mesh.uvs) uvs = ' '.join([f'{uv[0]} {uv[1]}' for uv in mesh.uvs]) num_vertex_colors = len(mesh.colors) vertex_colors = ' '.join([f'{c[0]} {c[1]} {c[2]} {c[3]}' for c in mesh.colors]) texture_name = texture_name.replace('.','_') # print(vertices) text = f''' Ursina User ursina Y_UP {texture_name} {texture_name}-surface 0 0 0 1 1.45 {vertices} 0 0 1 0 -1 0 -1 0 0 0 0 -1 1 0 0 0 1 0 {uvs} {vertex_colors}

{triangle_indices}

1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
''' with (folder / f'{name}.dae').open('w') as f: f.write(text) if __name__ == '__main__': from ursina import Ursina, Entity, load_model, EditorCamera, Sky app = Ursina() t = perf_counter() Entity(model='untitled') print('-------', perf_counter() - t) m = load_model('cube', use_deepcopy=True) ursinamesh_to_dae(m, 'dae_export_test.dae') EditorCamera() Sky(texture='sky_sunset') app.run()