diff --git a/assets/models/debugplane.glb b/assets/models/debugplane.glb index a48ca4b..d707fa2 100644 Binary files a/assets/models/debugplane.glb and b/assets/models/debugplane.glb differ diff --git a/assets/models/debugrot.glb b/assets/models/debugrot.glb new file mode 100644 index 0000000..11f665a Binary files /dev/null and b/assets/models/debugrot.glb differ diff --git a/source/packages/gui.py b/source/packages/gui.py new file mode 100644 index 0000000..4a5eb9e --- /dev/null +++ b/source/packages/gui.py @@ -0,0 +1,145 @@ +import posixpath +import tkinter as tk +import tkinter.ttk as ttk +import simplepbr +import gltf +from direct.stdpy.file import walk +from panda3d.core import NodePath, DirectionalLight, TransparencyAttrib + +def get_icons(): + return type('', (object,), { + 'app': tk.PhotoImage(file="icons/application.png"), + 'brick': tk.PhotoImage(file="icons/brick.png"), + 'bricks': tk.PhotoImage(file="icons/bricks.png"), + 'computer': tk.PhotoImage(file="icons/computer.png"), + 'folder': tk.PhotoImage(file="icons/folder.png"), + 'shape_group': tk.PhotoImage(file="icons/shape_group.png"), + 'pictures': tk.PhotoImage(file="icons/pictures.png"), + 'picture': tk.PhotoImage(file='icons/picture.png'), + "page_red": tk.PhotoImage(file='icons/page_red.png'), + 'shape_square': tk.PhotoImage(file='icons/shape_square.png'), + 'color_wheel': tk.PhotoImage(file='icons/color_wheel.png'), + 'color_swatch': tk.PhotoImage(file='icons/color_swatch.png'), + 'link': tk.PhotoImage(file='icons/link.png'), + 'sound': tk.PhotoImage(file='icons/sound.png'), + 'chart_organisation': tk.PhotoImage(file='icons/chart_organisation.png'), + 'anchor': tk.PhotoImage(file='icons/anchor.png'), + 'shape_flip_horizontal': tk.PhotoImage(file='icons/shape_flip_horizontal.png'), + 'film': tk.PhotoImage(file='icons/film.png'), + 'user': tk.PhotoImage(file='icons/user.png') + })() + +def add_package_contents_to_tree(tree, package, type, name, extensions, icon_folder, icon_group, icon_item): + data_path = posixpath.join(package.mount_dir, type) + tree.insert(package.mount_dir, 'end', data_path, text=f' {name}', image=icon_group) + file_count = 0 + for root, paths, files in walk(data_path): + for path in paths: + tree.insert(root, 'end', posixpath.join(root, path), text=f' {path}', image=icon_folder) + for file in files: + if file.lower().endswith(extensions): + file_count += 1 + tree.insert(root, 'end', posixpath.join(root, file), text=f' {file}', image=icon_item) + tree.item(data_path, text=f' {name} ({file_count})') + +def add_package_models_to_tree(tree, package, icons): + add_package_contents_to_tree(tree, package, 'models/', '3D Models', ('.glb', '.gltf', '.obj', '.egg'), icons.folder, icons.shape_group, icons.shape_square) + +def add_package_textures_to_tree(tree, package, icons): + add_package_contents_to_tree(tree, package, 'textures/', 'Image Textures', ('.png', '.jpg', '.bmp'), icons.folder, icons.pictures, icons.picture) + +def add_package_materials_to_tree(tree, package, icons): + add_package_contents_to_tree(tree, package, 'materials/', 'Materials', ('.json'), icons.folder, icons.color_wheel, icons.color_swatch) + +def add_package_sounds_to_tree(tree, package, icons): + add_package_contents_to_tree(tree, package, 'sounds/', 'Sounds', ('.ogg', '.wav'), icons.folder, icons.sound, icons.sound) + +def add_package_to_tree(tree, package, icons): + add_package_models_to_tree(tree, package, icons) + add_package_textures_to_tree(tree, package, icons) + add_package_materials_to_tree(tree, package, icons) + add_package_sounds_to_tree(tree, package, icons) + +def init_packages_tree(tree, packages, icons): + tree.insert('', 'end', '/', text=' /', open=True, image=icons.app) + tree.insert('/', 'end', '/main/', text=f' Main Package "{packages.main_package.meta.name}" - {packages.main_package.meta.version}', image=icons.computer) + tree.insert('/', 'end', '/include/', text=f' Included Packages ({len(packages.package_list)})', image=icons.bricks) + add_package_to_tree(tree, packages.main_package, icons) + for package in packages.package_list: + tree.insert('/include/', 'end', package.mount_dir, text=f' "{package.meta.name}" - {package.meta.version}', image=icons.brick) + add_package_to_tree(tree, package, icons) + return tree + +def init_gui(app, args): + app.gui.geometry("700x500") + app.gui.grid_rowconfigure(0, weight=10) + app.gui.grid_rowconfigure(1, weight=5) + app.gui.grid_columnconfigure(0, weight=1) + package_frame = tk.Frame(app.gui, padx=4, pady=4) + package_frame.grid(column=0, row=0, sticky="news") + package_frame.grid_columnconfigure(0, weight=1) + package_frame.grid_rowconfigure(0, weight=1) + package_frame.grid_rowconfigure(1, weight=1000) + packages_label = tk.Label(package_frame, text="Packages") + packages_label.grid(column=0, row=0, sticky="w") + packagetree_frame = tk.Frame(package_frame) + packagetree_frame.grid(column=0, row=1, sticky="news") + packagetree_frame.grid_columnconfigure(0, weight=1000) + packagetree_frame.grid_columnconfigure(1, weight=1) + packagetree_frame.grid_rowconfigure(0, weight=1) + app.tree_packages = ttk.Treeview(packagetree_frame, show="tree") + app.tree_packages.grid(column=0, row=0, sticky="news") + packagetree_scrollbar = ttk.Scrollbar(packagetree_frame, orient="vertical", command=app.tree_packages.yview) + packagetree_scrollbar.grid(column=1, row=0) + app.tree_packages.bind('', app.on_packagetree_doubleclick) + scene_frame = tk.Frame(app.gui, padx=4, pady=4) + scene_frame.grid(column=0, row=1, sticky="news") + scene_frame.grid_columnconfigure(0, weight=1) + scene_frame.grid_rowconfigure(0, weight=1) + scene_frame.grid_rowconfigure(1, weight=1000) + scene_label = tk.Label(scene_frame, text="Scene Graph") + scene_label.grid(column=0, row=0, sticky="w") + scenetree_frame = tk.Frame(scene_frame) + scenetree_frame.grid(column=0, row=1, sticky="news") + scenetree_frame.grid_columnconfigure(0, weight=10000) + scenetree_frame.grid_columnconfigure(1, weight=1) + scenetree_frame.grid_rowconfigure(0, weight=1) + app.tree_scene = ttk.Treeview(scenetree_frame, show="tree") + app.tree_scene.grid(column=0, row=0, sticky="news") + scenetree_scrollbar = ttk.Scrollbar(scenetree_frame, orient="vertical", command=app.tree_scene.yview) + scenetree_scrollbar.grid(column=1, row=0) + app.gui.protocol("WM_DELETE_WINDOW", app.on_tk_close) + +def init_panda(app, args): + gltf.patch_loader(app.panda.loader) + app.panda.setBackgroundColor(0, 0, 0) + app.panda.disableMouse() + app.panda.camera.setPos(-5, -5, 2.5) + app.panda.camera.setHpr(-45, -20, 0) + simplepbr.init() + env_root = NodePath('env_root') + env_root.reparentTo(app.panda.render) + axis = app.panda.loader.loadModel(app.package_manager.get_model_path('axis.glb')) + axis.setTransparency(TransparencyAttrib.MAlpha) + axis.setAlphaScale(0.2) + axis.reparentTo(env_root) + plane = app.panda.loader.loadModel(app.package_manager.get_model_path('debugplane.glb')) + plane.setTransparency(TransparencyAttrib.MAlpha) + plane.setAlphaScale(0.4) + plane.reparentTo(env_root) + root = app.panda.loader.loadModel(app.package_manager.get_model_path('debugrot.glb')) + root.setTransparency(TransparencyAttrib.MAlpha) + root.setAlphaScale(0.4) + root.reparentTo(env_root) + dlight = DirectionalLight('light') + dlight.setColor((4, 4, 4, 1)) + dlight.setShadowCaster(True, 512, 512) + nplight = env_root.attachNewNode(dlight) + nplight.setPos(0, 0, -1) + nplight.setHpr(0, -60, -45) + app.panda.render.setLight(nplight) + app.scene_root = NodePath('scene_root') + app.scene_root.reparentTo(app.panda.render) + app.panda.taskMgr.add(app.update_input, "update_input") + app.panda.accept('mouse1', app.mouse1_down, []) + app.panda.accept('mouse1-up', app.mouse1_up, []) \ No newline at end of file diff --git a/source/packages/manager.py b/source/packages/manager.py index 3edd651..702ca42 100644 --- a/source/packages/manager.py +++ b/source/packages/manager.py @@ -44,7 +44,6 @@ class PackageManager: def get_model_path(self, name): for imported_package in reversed(self.package_list): target_path = posixpath.join(imported_package.mount_dir, 'models', name) - print(target_path) if self.vfs.exists(target_path): return target_path main_path = posixpath.join(self.main_package.mount_dir, 'models', name) diff --git a/source/pkgexplore.py b/source/pkgexplore.py index 9f68a81..49538fd 100644 --- a/source/pkgexplore.py +++ b/source/pkgexplore.py @@ -1,117 +1,9 @@ -import posixpath + import tkinter as tk -import tkinter.ttk as ttk from source.packages import PackageManager +from source.packages.gui import * from direct.showbase.ShowBase import ShowBase -from panda3d.core import VirtualFileSystem, Material, NodePath -from direct.stdpy.file import walk - -import simplepbr -import gltf - -def get_icons(): - return type('', (object,), { - 'app': tk.PhotoImage(file="icons/application.png"), - 'brick': tk.PhotoImage(file="icons/brick.png"), - 'bricks': tk.PhotoImage(file="icons/bricks.png"), - 'computer': tk.PhotoImage(file="icons/computer.png"), - 'folder': tk.PhotoImage(file="icons/folder.png"), - 'shape_group': tk.PhotoImage(file="icons/shape_group.png"), - 'pictures': tk.PhotoImage(file="icons/pictures.png"), - 'picture': tk.PhotoImage(file='icons/picture.png'), - "page_red": tk.PhotoImage(file='icons/page_red.png'), - 'shape_square': tk.PhotoImage(file='icons/shape_square.png'), - 'color_wheel': tk.PhotoImage(file='icons/color_wheel.png'), - 'color_swatch': tk.PhotoImage(file='icons/color_swatch.png'), - 'link': tk.PhotoImage(file='icons/link.png'), - 'sound': tk.PhotoImage(file='icons/sound.png'), - 'chart_organisation': tk.PhotoImage(file='icons/chart_organisation.png'), - 'anchor': tk.PhotoImage(file='icons/anchor.png'), - 'shape_flip_horizontal': tk.PhotoImage(file='icons/shape_flip_horizontal.png'), - 'film': tk.PhotoImage(file='icons/film.png'), - 'user': tk.PhotoImage(file='icons/user.png') - })() - -def add_package_contents_to_tree(tree, package, type, name, extensions, icon_folder, icon_group, icon_item): - data_path = posixpath.join(package.mount_dir, type) - tree.insert(package.mount_dir, 'end', data_path, text=f' {name}', image=icon_group) - file_count = 0 - for root, paths, files in walk(data_path): - for path in paths: - tree.insert(root, 'end', posixpath.join(root, path), text=f' {path}', image=icon_folder) - for file in files: - if file.lower().endswith(extensions): - file_count += 1 - tree.insert(root, 'end', posixpath.join(root, file), text=f' {file}', image=icon_item) - tree.item(data_path, text=f' {name} ({file_count})') - -def add_package_models_to_tree(tree, package, icons): - add_package_contents_to_tree(tree, package, 'models/', '3D Models', ('.glb', '.gltf', '.obj', '.egg'), icons.folder, icons.shape_group, icons.shape_square) - -def add_package_textures_to_tree(tree, package, icons): - add_package_contents_to_tree(tree, package, 'textures/', 'Image Textures', ('.png', '.jpg', '.bmp'), icons.folder, icons.pictures, icons.picture) - -def add_package_materials_to_tree(tree, package, icons): - add_package_contents_to_tree(tree, package, 'materials/', 'Materials', ('.json'), icons.folder, icons.color_wheel, icons.color_swatch) - -def add_package_sounds_to_tree(tree, package, icons): - add_package_contents_to_tree(tree, package, 'sounds/', 'Sounds', ('.ogg', '.wav'), icons.folder, icons.sound, icons.sound) - -def add_package_to_tree(tree, package, icons): - add_package_models_to_tree(tree, package, icons) - add_package_textures_to_tree(tree, package, icons) - add_package_materials_to_tree(tree, package, icons) - add_package_sounds_to_tree(tree, package, icons) - -def init_packages_tree(tree, packages, icons): - tree.insert('', 'end', '/', text=' /', open=True, image=icons.app) - tree.insert('/', 'end', '/main/', text=f' Main Package "{packages.main_package.meta.name}" - {packages.main_package.meta.version}', image=icons.computer) - tree.insert('/', 'end', '/include/', text=f' Included Packages ({len(packages.package_list)})', image=icons.bricks) - add_package_to_tree(tree, packages.main_package, icons) - for package in packages.package_list: - tree.insert('/include/', 'end', package.mount_dir, text=f' "{package.meta.name}" - {package.meta.version}', image=icons.brick) - add_package_to_tree(tree, package, icons) - return tree - -def init_gui(app, args): - app.gui.geometry("700x500") - app.gui.grid_rowconfigure(0, weight=10) - app.gui.grid_rowconfigure(1, weight=5) - app.gui.grid_columnconfigure(0, weight=1) - package_frame = tk.Frame(app.gui, padx=4, pady=4) - package_frame.grid(column=0, row=0, sticky="news") - package_frame.grid_columnconfigure(0, weight=1) - package_frame.grid_rowconfigure(0, weight=1) - package_frame.grid_rowconfigure(1, weight=1000) - packages_label = tk.Label(package_frame, text="Packages") - packages_label.grid(column=0, row=0, sticky="w") - packagetree_frame = tk.Frame(package_frame) - packagetree_frame.grid(column=0, row=1, sticky="news") - packagetree_frame.grid_columnconfigure(0, weight=1000) - packagetree_frame.grid_columnconfigure(1, weight=1) - packagetree_frame.grid_rowconfigure(0, weight=1) - app.tree_packages = ttk.Treeview(packagetree_frame, show="tree") - app.tree_packages.grid(column=0, row=0, sticky="news") - packagetree_scrollbar = ttk.Scrollbar(packagetree_frame, orient="vertical", command=app.tree_packages.yview) - packagetree_scrollbar.grid(column=1, row=0) - app.tree_packages.bind('', app.on_packagetree_doubleclick) - - scene_frame = tk.Frame(app.gui, padx=4, pady=4) - scene_frame.grid(column=0, row=1, sticky="news") - scene_frame.grid_columnconfigure(0, weight=1) - scene_frame.grid_rowconfigure(0, weight=1) - scene_frame.grid_rowconfigure(1, weight=1000) - scene_label = tk.Label(scene_frame, text="Scene Graph") - scene_label.grid(column=0, row=0, sticky="w") - scenetree_frame = tk.Frame(scene_frame) - scenetree_frame.grid(column=0, row=1, sticky="news") - scenetree_frame.grid_columnconfigure(0, weight=10000) - scenetree_frame.grid_columnconfigure(1, weight=1) - scenetree_frame.grid_rowconfigure(0, weight=1) - app.tree_scene = ttk.Treeview(scenetree_frame, show="tree") - app.tree_scene.grid(column=0, row=0, sticky="news") - scenetree_scrollbar = ttk.Scrollbar(scenetree_frame, orient="vertical", command=app.tree_scene.yview) - scenetree_scrollbar.grid(column=1, row=0) +from panda3d.core import VirtualFileSystem, Material class PackageExplorer: def __init__(self, args): @@ -127,25 +19,12 @@ class PackageExplorer: self.tree_packages = None self.tree_scene = None self.running = True - simplepbr.init() - gltf.patch_loader(self.panda.loader) + self.panda_keymap = { + 'mouse1': False + } init_gui(self, args) init_packages_tree(self.tree_packages, self.package_manager, self.icons) - - env_root = NodePath('env_root') - env_root.reparentTo(self.panda.render) - - axis = self.panda.loader.loadModel(self.package_manager.get_model_path('axis.glb')) - axis.reparentTo(env_root) - - plane = self.panda.loader.loadModel(self.package_manager.get_model_path('debugplane.glb')) - plane.reparentTo(env_root) - - self.scene_root = NodePath('scene_root') - self.scene_root.reparentTo(self.panda.render) - - - self.gui.protocol("WM_DELETE_WINDOW", self.on_tk_close) + init_panda(self, args) def on_tk_close(self): self.running = False @@ -182,16 +61,28 @@ class PackageExplorer: image = self.icons.shape_flip_horizontal case 'AnimBundleNode': bundle = pn.getBundle().getName() - tree_id = f'{tree_id}_"{bundle}"' - tree_name = f'"{bundle}"' + tree_id = f'{tree_id}_{bundle}' + tree_name = f'{bundle}' image = self.icons.film case 'Character': image = self.icons.user - self.tree_scene.insert(parent, 'end', tree_id, text=f' {tree_name}', open=True, image=image) for child in node.getChildren(): self.add_scene_nodes(child, tree_id) + def mouse1_down(self): + self.panda_keymap['mouse1'] = True + + def mouse1_up(self): + self.panda_keymap['mouse1'] = False + + def update_input(self, task): + dt = self.panda.clock.getDt() + if self.panda_keymap['mouse1']: + print('Mouse1 down') + + return task.cont + def loop(self): try: while self.running: