MetaCoreEngineV2/classes/gameobject.py
2026-01-13 17:06:06 +08:00

90 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import direct
import direct.showbase
import direct.showbase.ShowBaseGlobal
import panda3d.core as p3d
from direct.showbase.ShowBase import ShowBase
from panda3d.core import NodePath
class GameObject(NodePath):
def __init__(self, model: NodePath):
self = model
self.gameobject = self
self.self_active = self.is_hidden()
def set_active(self, active: bool):
if active:self.show()
else:self.hide()
@classmethod
def create_panel(self) -> NodePath:
base = direct.showbase.ShowBaseGlobal.base
if not base or not base.render:
raise Exception("base or base.render is None")
from panda3d.core import CardMaker
cm = CardMaker("ground")
cm.set_frame(-10, 10, -10, 10) # (left, right, bottom, top)
plane_np = base.render.attach_new_node(cm.generate())
plane_np.set_hpr(0, -90, 0) # 躺平(默认是 XY 平面,朝 +Z
plane_np.setTwoSided(True)
mat = p3d.Material('unlit')
plane_np.set_material(mat)
return plane_np
@classmethod
def set_model_auto_scale(self, model: NodePath,debug_info = False):
base = direct.showbase.ShowBaseGlobal.base
if not base or not base.render:
raise Exception("base or base.render is None")
if not model or model.is_empty():
return
bmin, bmax = model.get_tight_bounds(base.render)
if bmin is None or bmax is None:
return
size = bmax - bmin
max_size = max(size.x, size.y, size.z)
if max_size <= 0:
return
# 目标:让最大边缩放到略小于 10比如 9.9
target_max = 3
scale_factor = target_max / max_size
model.set_scale(scale_factor)
if debug_info:
print(f"自动缩放:原最大尺寸={max_size:.3f} → 缩放因子={scale_factor:.6f}")
@classmethod
def get_node_type(self,np: NodePath) -> str:
node = np.node()
if isinstance(node, p3d.GeomNode):
return "mesh(GeomNode)"
if isinstance(node, p3d.CollisionNode):
return "collision(CollisionNode)"
if isinstance(node, p3d.Camera):
return "camera"
if isinstance(node, p3d.Light):
return "light"
if isinstance(node, p3d.TextNode):
return "text"
# 不同节点可能是模型根、LOD根等但核心是是否包含 Geom/Collision
if not np.find("**/+GeomNode").isEmpty():
return "empty*"
if not np.find("**/+CollisionNode").isEmpty():
return "collision_parent*"
return "empty"
@classmethod
def get_child_name(self,node:NodePath):
if not node or node.isEmpty() or node.getNumChildren() == 0:return
for n in node.getChildren():
print(f"{n.getName()} -> {GameObject.get_node_type(n)}")
GameObject.get_child_name(n)
return f"empty/transform({node.getType().getName()})"