184 lines
7.1 KiB
Python
184 lines
7.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
测试脚本:验证子节点的选择框和坐标轴跟随父模型移动
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
from main import MyWorld
|
|
from panda3d.core import Vec3, Point3, CardMaker, GeomNode
|
|
from direct.task.TaskManagerGlobal import taskMgr
|
|
import time
|
|
|
|
def getWorldCenter(nodePath, render):
|
|
"""获取节点在世界坐标系中的边界框中心"""
|
|
minPoint = Point3()
|
|
maxPoint = Point3()
|
|
if nodePath.calcTightBounds(minPoint, maxPoint, render):
|
|
return Point3((minPoint.x + maxPoint.x) * 0.5,
|
|
(minPoint.y + maxPoint.y) * 0.5,
|
|
(minPoint.z + maxPoint.z) * 0.5)
|
|
return Point3(0, 0, 0)
|
|
|
|
def test_selection_follow():
|
|
"""测试子节点选择框和坐标轴跟随父模型移动"""
|
|
print("=== 测试子节点选择框和坐标轴跟随 ===")
|
|
|
|
# 创建世界
|
|
world = MyWorld()
|
|
|
|
# 创建主父节点
|
|
parent = world.render.attachNewNode("parent_model")
|
|
|
|
# 创建子节点1 - 一个简单的几何体
|
|
cm1 = CardMaker("child1_card")
|
|
cm1.setFrame(-1, 1, -1, 1)
|
|
child1 = parent.attachNewNode(cm1.generate())
|
|
child1.setName("child1")
|
|
child1.setPos(2, 0, 0) # 相对于父节点的位置
|
|
child1.setColor(1, 0, 0, 1) # 红色
|
|
|
|
# 创建子节点2 - 另一个几何体
|
|
cm2 = CardMaker("child2_card")
|
|
cm2.setFrame(-0.5, 0.5, -0.5, 0.5)
|
|
child2 = parent.attachNewNode(cm2.generate())
|
|
child2.setName("child2")
|
|
child2.setPos(-2, 0, 1) # 相对于父节点的位置
|
|
child2.setColor(0, 1, 0, 1) # 绿色
|
|
|
|
# 设置父节点的初始位置
|
|
parent.setPos(0, 0, 0)
|
|
|
|
# 将父节点添加到模型列表(这样它可以被选择)
|
|
world.models.append(parent)
|
|
world.models.append(child1)
|
|
world.models.append(child2)
|
|
|
|
print(f"创建了父节点: {parent.getName()}")
|
|
print(f"创建了子节点1: {child1.getName()}, 位置: {child1.getPos()}")
|
|
print(f"创建了子节点2: {child2.getName()}, 位置: {child2.getPos()}")
|
|
|
|
# 选择子节点1
|
|
print("\n--- 选择子节点1 ---")
|
|
world.selection.updateSelection(child1)
|
|
|
|
print(f"子节点1的相对边界框: {child1.getBounds()}")
|
|
|
|
# 获取移动后的世界边界框
|
|
minPoint = Point3()
|
|
maxPoint = Point3()
|
|
if child1.calcTightBounds(minPoint, maxPoint, world.render):
|
|
print(f"子节点1的世界边界框: min={minPoint}, max={maxPoint}")
|
|
else:
|
|
print("子节点1无法计算世界边界框")
|
|
|
|
# 移动父节点
|
|
print("\n--- 移动父节点到新位置 ---")
|
|
new_parent_pos = Vec3(5, 3, 2)
|
|
parent.setPos(new_parent_pos)
|
|
|
|
print(f"父节点新位置: {parent.getPos()}")
|
|
print(f"子节点1的相对边界框: {child1.getBounds()}")
|
|
|
|
# 获取移动后的世界边界框
|
|
minPoint = Point3()
|
|
maxPoint = Point3()
|
|
if child1.calcTightBounds(minPoint, maxPoint, world.render):
|
|
print(f"子节点1的世界边界框: min={minPoint}, max={maxPoint}")
|
|
else:
|
|
print("子节点1无法计算世界边界框")
|
|
|
|
# 等待一帧,让更新任务运行
|
|
def check_after_move(task):
|
|
print("\n--- 检查移动后的状态 ---")
|
|
|
|
# 检查选择框是否跟随
|
|
if world.selection.selectionBox:
|
|
# 获取选择框目标的世界边界框
|
|
minPoint = Point3()
|
|
maxPoint = Point3()
|
|
if world.selection.selectionBoxTarget.calcTightBounds(minPoint, maxPoint, world.render):
|
|
print(f"选择框目标的世界边界框: min={minPoint}, max={maxPoint}")
|
|
print(f"选择框是否存在: {world.selection.selectionBox is not None}")
|
|
|
|
# 检查坐标轴是否跟随
|
|
if world.selection.gizmo:
|
|
gizmo_pos = world.selection.gizmo.getPos()
|
|
print(f"坐标轴位置: {gizmo_pos}")
|
|
|
|
# 验证坐标轴是否在正确的位置
|
|
expected_center = getWorldCenter(child1, world.render)
|
|
print(f"期望的坐标轴位置: {expected_center}")
|
|
|
|
# 计算位置差异
|
|
diff = (gizmo_pos - expected_center).length()
|
|
print(f"坐标轴位置差异: {diff}")
|
|
|
|
if diff < 0.1: # 允许小的浮点误差
|
|
print("✓ 坐标轴正确跟随了父模型移动")
|
|
else:
|
|
print("✗ 坐标轴没有正确跟随父模型移动")
|
|
|
|
# 再次移动父节点测试
|
|
print("\n--- 再次移动父节点 ---")
|
|
another_pos = Vec3(-3, -2, 1)
|
|
parent.setPos(another_pos)
|
|
print(f"父节点再次移动到: {another_pos}")
|
|
|
|
# 等待另一帧
|
|
def final_check(task):
|
|
print("\n--- 最终检查 ---")
|
|
if world.selection.gizmo:
|
|
final_gizmo_pos = world.selection.gizmo.getPos()
|
|
final_expected_center = getWorldCenter(child1, world.render)
|
|
final_diff = (final_gizmo_pos - final_expected_center).length()
|
|
|
|
print(f"最终坐标轴位置: {final_gizmo_pos}")
|
|
print(f"最终期望位置: {final_expected_center}")
|
|
print(f"最终位置差异: {final_diff}")
|
|
|
|
if final_diff < 0.1:
|
|
print("✓ 测试通过:坐标轴正确跟随父模型移动")
|
|
else:
|
|
print("✗ 测试失败:坐标轴没有正确跟随")
|
|
|
|
# 测试选择其他子节点
|
|
print("\n--- 测试选择子节点2 ---")
|
|
world.selection.updateSelection(child2)
|
|
|
|
def check_child2(task):
|
|
if world.selection.gizmo:
|
|
child2_gizmo_pos = world.selection.gizmo.getPos()
|
|
child2_expected_center = getWorldCenter(child2, world.render)
|
|
child2_diff = (child2_gizmo_pos - child2_expected_center).length()
|
|
|
|
print(f"子节点2坐标轴位置: {child2_gizmo_pos}")
|
|
print(f"子节点2期望位置: {child2_expected_center}")
|
|
print(f"子节点2位置差异: {child2_diff}")
|
|
|
|
if child2_diff < 0.1:
|
|
print("✓ 子节点2坐标轴位置正确")
|
|
else:
|
|
print("✗ 子节点2坐标轴位置错误")
|
|
|
|
print("\n=== 测试完成 ===")
|
|
return task.done
|
|
|
|
taskMgr.doMethodLater(0.1, check_child2, "check_child2")
|
|
return task.done
|
|
|
|
taskMgr.doMethodLater(0.1, final_check, "final_check")
|
|
return task.done
|
|
|
|
taskMgr.doMethodLater(0.1, check_after_move, "check_after_move")
|
|
|
|
# 运行测试
|
|
print("\n开始运行测试...")
|
|
world.run()
|
|
|
|
if __name__ == "__main__":
|
|
test_selection_follow() |