Scene graph tree added
BIN
assets/models/debugplane.glb
Normal file
BIN
icons/anchor.png
Normal file
After Width: | Height: | Size: 523 B |
BIN
icons/chart_organisation.png
Normal file
After Width: | Height: | Size: 434 B |
BIN
icons/film.png
Normal file
After Width: | Height: | Size: 653 B |
BIN
icons/link.png
Normal file
After Width: | Height: | Size: 343 B |
BIN
icons/shape_flip_horizontal.png
Normal file
After Width: | Height: | Size: 403 B |
BIN
icons/sound.png
Normal file
After Width: | Height: | Size: 610 B |
BIN
icons/user.png
Normal file
After Width: | Height: | Size: 741 B |
@ -1,5 +1,6 @@
|
||||
|
||||
import os, json
|
||||
import posixpath
|
||||
from .package import Package
|
||||
from .errors import *
|
||||
|
||||
@ -39,3 +40,14 @@ class PackageManager:
|
||||
new_package = Package(type('', (object,), meta), vfs_path, self.vfs)
|
||||
self.package_map[meta['name']] = new_package
|
||||
self.package_list.insert(0, new_package)
|
||||
|
||||
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)
|
||||
if (self.vfs.exists(main_path)):
|
||||
return main_path
|
||||
return None
|
||||
|
@ -3,7 +3,7 @@ import tkinter as tk
|
||||
import tkinter.ttk as ttk
|
||||
from source.packages import PackageManager
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
from panda3d.core import VirtualFileSystem, Material, WindowProperties
|
||||
from panda3d.core import VirtualFileSystem, Material, NodePath
|
||||
from direct.stdpy.file import walk
|
||||
|
||||
import simplepbr
|
||||
@ -22,7 +22,14 @@ def get_icons():
|
||||
"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')
|
||||
'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):
|
||||
@ -47,10 +54,14 @@ def add_package_textures_to_tree(tree, package, icons):
|
||||
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)
|
||||
@ -65,7 +76,7 @@ def init_packages_tree(tree, packages, icons):
|
||||
def init_gui(app, args):
|
||||
app.gui.geometry("700x500")
|
||||
app.gui.grid_rowconfigure(0, weight=10)
|
||||
app.gui.grid_rowconfigure(0, weight=1)
|
||||
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")
|
||||
@ -108,6 +119,8 @@ class PackageExplorer:
|
||||
self.panda = ShowBase()
|
||||
self.package_manager = PackageManager(VirtualFileSystem.getGlobalPtr())
|
||||
self.package_manager.set_main_package(args.main)
|
||||
self.icons = get_icons()
|
||||
self.prev = None
|
||||
if args.package:
|
||||
for include in args.package:
|
||||
self.package_manager.include_package(include)
|
||||
@ -117,7 +130,21 @@ class PackageExplorer:
|
||||
simplepbr.init()
|
||||
gltf.patch_loader(self.panda.loader)
|
||||
init_gui(self, args)
|
||||
init_packages_tree(self.tree_packages, self.package_manager, get_icons())
|
||||
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)
|
||||
|
||||
def on_tk_close(self):
|
||||
@ -126,18 +153,51 @@ class PackageExplorer:
|
||||
def on_packagetree_doubleclick(self, event):
|
||||
item = self.tree_packages.selection()[0]
|
||||
if item.lower().endswith(('.glb', '.gltf', '.obj', '.egg')):
|
||||
for child in self.scene_root.getChildren():
|
||||
child.removeNode()
|
||||
mat = Material()
|
||||
mat.setAmbient((1, 0, 0, 1))
|
||||
node = self.panda.loader.loadModel(item)
|
||||
node.reparentTo(self.panda.render)
|
||||
node.reparentTo(self.scene_root)
|
||||
node.setMaterial(mat)
|
||||
self.display_scenegraph(node, item)
|
||||
self.prev = node
|
||||
|
||||
def display_scenegraph(self, node, item):
|
||||
self.tree_scene.delete(*self.tree_scene.get_children())
|
||||
self.tree_scene.insert('', 'end', '/', text=f' {item}', open=True, image=self.icons.shape_square)
|
||||
self.add_scene_nodes(node, '/')
|
||||
|
||||
def add_scene_nodes(self, node, parent):
|
||||
pn = node.node()
|
||||
tree_id = f'{pn.getType().getName()} {node.getName()}'
|
||||
tree_name = tree_id
|
||||
image = ''
|
||||
match pn.getType().getName():
|
||||
case 'ModelRoot':
|
||||
image = self.icons.chart_organisation
|
||||
case 'PandaNode':
|
||||
image = self.icons.anchor
|
||||
case 'GeomNode':
|
||||
image = self.icons.shape_flip_horizontal
|
||||
case 'AnimBundleNode':
|
||||
bundle = pn.getBundle().getName()
|
||||
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 loop(self):
|
||||
try:
|
||||
while self.running:
|
||||
self.panda.taskMgr.step()
|
||||
self.gui.update_idletasks()
|
||||
self.gui.update()
|
||||
self.panda.taskMgr.step()
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
|
||||
|