MBH_Demo_001/source/filesystem.py

101 lines
2.4 KiB
Python
Raw Normal View History

2023-01-17 21:54:39 +01:00
import os
import posixpath
import json
from panda3d.core import VirtualFileSystem
class PackageNotFound(FileNotFoundError):
pass
class PackageMetaNotFound(FileNotFoundError):
pass
class PackageInvalid(FileNotFoundError):
pass
class PackageDuplicate(FileNotFoundError):
pass
class Package:
def __init__(self, name, vfs_dir):
self.name = name
self.vfs_dir = vfs_dir
class Filesystem:
def __init__(self):
self.package_list = []
self.package_map = {}
self.vfs = VirtualFileSystem.getGlobalPtr()
self.include('assets/')
self.mdl_missing = loader.loadModel('/main-assets/models/missing.glb')
self.mdl_missing.setTexture(loader.loadTexture('/main-assets/textures/missing_mdl.png'))
self.tex_missing = loader.loadTexture('/main-assets/textures/missing_tex.png')
def include(self, path):
if not os.path.exists(path):
raise PackageNotFound(path)
gamepkg_path = os.path.join(path, 'gamepackage.json')
if not os.path.exists(gamepkg_path):
raise PackageMetaNotFound(path)
meta = json.load(open(gamepkg_path))
if 'name' not in meta:
raise PackageInvalid(path)
if meta['name'] in self.package_map:
raise PackageDuplicate(meta['name'])
vfs_path = f'/{meta["name"]}'
vfs.mount(path, f'/{meta["name"]}', 0)
new_package = Package(meta["name"], vfs_path)
self.package_map[meta['name']] = new_package
self.package_list.insert(0, new_package)
def find_texture(self, tex_path):
try:
if tex_path[0:2] == '$/':
for package in self.package_list:
path = posixpath.join('/', package.name, 'textures', tex_path[2:])
if self.vfs.exists(path):
return loader.loadTexture(path)
return self.tex_missing
else:
resource_path = model_path.split('/')
path = posixpath.join('/', resource_path[0], 'textures', '/'.join(resource_path[1:]))
return loader.loadTexture(path)
except IOError:
return self.tex_missing
def find_model(self, model_path):
try:
if model_path[0:2] == '$/':
for package in self.package_list:
path = posixpath.join('/', package.name, 'models', model_path[2:])
if self.vfs.exists(path):
return loader.loadModel(path)
return self.mdl_missing
else:
resource_path = model_path.split('/')
path = posixpath.join('/', resource_path[0], 'models', '/'.join(resource_path[1:]))
return loader.loadModel(path)
except IOError:
return self.mdl_missing