Skip to content

Commit

Permalink
made all the asset importers work in similar ways and made them get t…
Browse files Browse the repository at this point in the history
…he updated folder paths each time, to make sure they don't break if you cange the asset_folder. also renamed some of the folders to keep the naming consistent with the actual folder names.
  • Loading branch information
pokepetter committed Oct 27, 2024
1 parent 21b965a commit 7841409
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 80 deletions.
5 changes: 2 additions & 3 deletions ursina/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

internal_models_folder = package_folder / 'models/'
internal_models_compressed_folder = package_folder / 'models_compressed/'
internal_prefabs_folder = package_folder / 'prefabs/'
internal_scripts_folder = package_folder / 'scripts/'
internal_textures_folder = package_folder / 'textures/'
internal_fonts_folder = package_folder / 'fonts/'
Expand All @@ -41,8 +40,8 @@
scripts_folder = asset_folder / 'scripts/'
fonts_folder = asset_folder / 'fonts/'

compressed_textures_folder = asset_folder / 'textures_compressed/'
compressed_models_folder = asset_folder / 'models_compressed/'
textures_compressed_folder = asset_folder / 'textures_compressed/'
models_compressed_folder = asset_folder / 'models_compressed/'

# fonts are loaded py panda3d, so add paths here
_model_path = getModelPath()
Expand Down
22 changes: 9 additions & 13 deletions ursina/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,26 +195,22 @@ def model_setter(self, value): # set model with model='model_name' (without fil
self._model = value

elif isinstance(value, str): # pass model asset name
m = load_model(value, application.asset_folder)
m = load_model(value)
if not m:
m = load_model(value, application.internal_models_compressed_folder)
if m:
if self.model is not None:
self.model.removeNode()

m.name = value
m.setPos(Vec3(0,0,0))
self._model = m
# import mesh_importer
# if not value in mesh_importer.imported_meshes:
# print_info('loaded model successfully:', value)
else:
if application.raise_exception_on_missing_model:
raise ValueError(f"missing model: '{value}'")

print_warning(f"missing model: '{value}'")
return

if self.model is not None:
self.model.removeNode()

m.name = value
m.setPos(Vec3(0,0,0))
self._model = m


if self._model:
self._model.reparentTo(self)
self._model.setTransparency(TransparencyAttrib.M_dual)
Expand Down
111 changes: 61 additions & 50 deletions ursina/mesh_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@
import gltf
import builtins
from ursina.sequence import Func
from ursina import application


imported_meshes = dict()
blender_scenes = dict()
# folders = (application.asset_folder, )

def load_model(name, folder=Func(getattr, application, 'asset_folder'), file_types=('.bam', '.ursinamesh', '.obj', '.glb', '.gltf', '.blend'), use_deepcopy=False, gltf_no_srgb=Func(getattr, application, 'gltf_no_srgb')):
if callable(folder):
folder = folder()
def load_model(name, folder=None, file_types=('.bam', '.ursinamesh', '.obj', '.glb', '.gltf', '.blend'), use_deepcopy=False, gltf_no_srgb=Func(getattr, application, 'gltf_no_srgb')):
if callable(gltf_no_srgb):
gltf_no_srgb = gltf_no_srgb()

if not isinstance(name, str):
raise TypeError(f"Argument save must be of type str, not {type(str)}")


if '.' in name:
full_name = name
Expand All @@ -45,56 +46,66 @@ def load_model(name, folder=Func(getattr, application, 'asset_folder'), file_typ
except:
pass

if folder is not None:
if not isinstance(folder, Path):
raise TypeError(f'folder must be a Path, not a {type(folder)}')
_folders = (folder,)

else:
_folders = (application.models_compressed_folder, application.asset_folder, application.internal_models_compressed_folder)


for filetype in file_types:
if use_deepcopy and filetype == '.bam':
continue
# warning: glob is case-insensitive on windows, so m.path will be all lowercase
for file_path in folder.glob(f'**/{name}{filetype}'):
if filetype == '.bam':
# print_info('loading bam')
return builtins.loader.loadModel(file_path) # type: ignore

if filetype == '.gltf' or filetype == '.glb':
gltf_settings = gltf.GltfSettings()
gltf_settings.no_srgb = gltf_no_srgb
model_root = gltf.load_model(str(file_path), gltf_settings=gltf_settings)
imported_meshes[name] = p3d.NodePath(model_root)
return p3d.NodePath(model_root)

if filetype == '.ursinamesh':
try:
with open(file_path) as f:
m = eval(f.read())
m.path = file_path
m.name = name
m.vertices = [Vec3(*v) for v in m.vertices]
imported_meshes[name] = m
return m
except:
raise Exception('invalid ursinamesh file:', file_path)


if filetype == '.obj':
# print('found obj', file_path)
m = obj_to_ursinamesh(folder=folder, name=name, return_mesh=True)
m.path = file_path
m.name = name
imported_meshes[name] = m
if not use_deepcopy:
m.save(f'{name}.bam')

return m

elif filetype == '.blend':
print_info('found blend file:', file_path)
if blend_to_obj(file_path):
# obj_to_ursinamesh(name=name)
return load_model(name, folder, use_deepcopy=use_deepcopy)
else:
try:
for folder in _folders:
# warning: glob is case-insensitive on windows, so m.path will be all lowercase
for file_path in folder.glob(f'**/{name}{filetype}'):
if filetype == '.bam':
# print_info('loading bam')
return builtins.loader.loadModel(file_path) # type: ignore
except:
pass

if filetype == '.gltf' or filetype == '.glb':
gltf_settings = gltf.GltfSettings()
gltf_settings.no_srgb = gltf_no_srgb
model_root = gltf.load_model(str(file_path), gltf_settings=gltf_settings)
imported_meshes[name] = p3d.NodePath(model_root)
return p3d.NodePath(model_root)

if filetype == '.ursinamesh':
try:
with open(file_path) as f:
m = eval(f.read())
m.path = file_path
m.name = name
m.vertices = [Vec3(*v) for v in m.vertices]
imported_meshes[name] = m
return m
except:
raise Exception('invalid ursinamesh file:', file_path)


if filetype == '.obj':
# print('found obj', file_path)
m = obj_to_ursinamesh(folder=folder, name=name, return_mesh=True)
m.path = file_path
m.name = name
imported_meshes[name] = m
if not use_deepcopy:
m.save(f'{name}.bam')

return m

elif filetype == '.blend':
print_info('found blend file:', file_path)
if blend_to_obj(file_path):
# obj_to_ursinamesh(name=name)
return load_model(name, folder, use_deepcopy=use_deepcopy)
else:
try:
return builtins.loader.loadModel(file_path) # type: ignore
except:
pass

return None

Expand Down Expand Up @@ -236,7 +247,7 @@ def blend_to_obj(blend_file:Path, out_folder=Func(getattr, application, 'compres
return exported


def obj_to_ursinamesh(folder=Func(getattr, application, 'compressed_models_folder'), out_folder=Func(getattr, application, 'compressed_models_folder'), name='*', return_mesh=True, save_to_file=False, delete_obj=False):
def obj_to_ursinamesh(folder=Func(getattr, application, 'models_compressed_folder'), out_folder=Func(getattr, application, 'models_compressed_folder'), name='*', return_mesh=True, save_to_file=False, delete_obj=False):
if callable(folder):
folder = folder()
if callable(out_folder):
Expand Down
2 changes: 1 addition & 1 deletion ursina/prefabs/frame_animation_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def __init__(self, name, fps=12, loop=True, autoplay=True, frame_times=None, aut
super().__init__(name=name)
self.play = self.start

model_folders = [application.compressed_models_folder, application.asset_folder]
model_folders = (application.models_compressed_folder, application.asset_folder)
model_names = find_sequence(name, ('*',), folders=model_folders)
if not model_names:
if application.raise_exception_on_missing_model:
Expand Down
21 changes: 8 additions & 13 deletions ursina/texture_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,24 @@

imported_textures = dict()
file_types = ('.tif', '.jpg', '.jpeg', '.png', '.gif')
folders = [ # folder search order
application.compressed_textures_folder,
application.asset_folder,
application.internal_textures_folder,
]
textureless = False


def load_texture(name, path=None, use_cache=True, filtering='default'):
def load_texture(name, folder=None, use_cache=True, filtering='default'):
if textureless:
return None

if use_cache and name in imported_textures:
return copy(imported_textures[name])

if folder is not None:
if not isinstance(folder, Path):
raise TypeError(f'folder must be a Path, not a {type(folder)}')
_folders = (folder,)

else:
_folders = (application.textures_compressed_folder, application.asset_folder, application.internal_textures_folder)

_folders = folders
# print('looking in:', _folders)
if path:
if isinstance(path, str):
_folders = (Path(path),)
else:
_folders = (path,)

if name.endswith('.mp4'):
for folder in _folders:
Expand Down

0 comments on commit 7841409

Please sign in to comment.