优化导入模型设置碰撞体的位置及大小与模型相对应
This commit is contained in:
parent
85f61bd78a
commit
e1b4731443
@ -14,7 +14,7 @@ from PyQt5.QtCore import Qt
|
|||||||
from PyQt5.QtWidgets import QTreeWidgetItem
|
from PyQt5.QtWidgets import QTreeWidgetItem
|
||||||
from panda3d.core import (
|
from panda3d.core import (
|
||||||
ModelPool, ModelRoot, Filename, NodePath, GeomNode, Material, Vec4, Vec3,
|
ModelPool, ModelRoot, Filename, NodePath, GeomNode, Material, Vec4, Vec3,
|
||||||
MaterialAttrib, ColorAttrib, Point3, CollisionNode, CollisionSphere,
|
MaterialAttrib, ColorAttrib, Point3, CollisionNode, CollisionSphere, CollisionBox,
|
||||||
BitMask32, TransparencyAttrib, LColor, TransformState, RenderModeAttrib
|
BitMask32, TransparencyAttrib, LColor, TransformState, RenderModeAttrib
|
||||||
)
|
)
|
||||||
import json
|
import json
|
||||||
@ -164,7 +164,7 @@ class SceneManager:
|
|||||||
#self._adjustModelToGround(model)
|
#self._adjustModelToGround(model)
|
||||||
|
|
||||||
# 创建并设置基础材质
|
# 创建并设置基础材质
|
||||||
print("\n=== 开始设置材质 ===")
|
#print("\n=== 开始设置材质 ===")
|
||||||
#self._applyMaterialsToModel(model)
|
#self._applyMaterialsToModel(model)
|
||||||
|
|
||||||
# 设置碰撞检测(重要!用于选择功能)
|
# 设置碰撞检测(重要!用于选择功能)
|
||||||
@ -718,7 +718,6 @@ class SceneManager:
|
|||||||
def setupCollision(self, model):
|
def setupCollision(self, model):
|
||||||
"""为模型设置碰撞检测(增强版本)"""
|
"""为模型设置碰撞检测(增强版本)"""
|
||||||
try:
|
try:
|
||||||
|
|
||||||
# 创建碰撞节点
|
# 创建碰撞节点
|
||||||
cNode = CollisionNode(f'modelCollision_{model.getName()}')
|
cNode = CollisionNode(f'modelCollision_{model.getName()}')
|
||||||
|
|
||||||
@ -734,39 +733,61 @@ class SceneManager:
|
|||||||
cNode.setIntoCollideMask(current_mask | model_collision_mask)
|
cNode.setIntoCollideMask(current_mask | model_collision_mask)
|
||||||
print(f"为 {model.getName()} 启用模型间碰撞检测")
|
print(f"为 {model.getName()} 启用模型间碰撞检测")
|
||||||
|
|
||||||
# 获取模型的边界
|
# 获取模型的边界信息,使用与选择框相同的计算方法
|
||||||
bounds = model.getBounds()
|
minPoint = Point3()
|
||||||
if bounds.isEmpty():
|
maxPoint = Point3()
|
||||||
print(f"⚠️ 模型 {model.getName()} 边界为空,使用默认碰撞体")
|
|
||||||
# 使用默认的小球体
|
# 使用与选择框相同的calcTightBounds方法获取边界
|
||||||
cSphere = CollisionSphere(Point3(0, 0, 0), 1.0)
|
if model.calcTightBounds(minPoint, maxPoint, self.world.render):
|
||||||
else:
|
# 检查边界框的有效性
|
||||||
center = bounds.getCenter()
|
if (abs(minPoint.x) < 1e10 and abs(minPoint.y) < 1e10 and abs(minPoint.z) < 1e10 and
|
||||||
radius = bounds.getRadius()
|
abs(maxPoint.x) < 1e10 and abs(maxPoint.y) < 1e10 and abs(maxPoint.z) < 1e10):
|
||||||
|
# 特殊处理FBX模型的碰撞体
|
||||||
# 确保半径不为零
|
if model.hasTag("model_path") and model.getTag("model_path").lower().endswith('.fbx'):
|
||||||
if radius <= 0:
|
print("检测到FBX模型,调整碰撞体...")
|
||||||
|
# 反向应用FBX的变换以匹配视觉表现
|
||||||
|
# 缩放调整: 乘以100(因为模型被缩小了0.01倍)
|
||||||
|
minPoint *= 100
|
||||||
|
maxPoint *= 100
|
||||||
|
|
||||||
|
# 旋转调整: 绕P轴旋转-90度
|
||||||
|
# 创建旋转矩阵
|
||||||
|
from panda3d.core import Mat4, LRotation
|
||||||
|
rotation = LRotation(0, -90, 0) # 绕P轴旋转-90度
|
||||||
|
rot_matrix = Mat4()
|
||||||
|
rotation.extractToMatrix(rot_matrix)
|
||||||
|
|
||||||
|
# 应用旋转变换到边界点
|
||||||
|
minPoint = rot_matrix.xformPoint(minPoint)
|
||||||
|
maxPoint = rot_matrix.xformPoint(maxPoint)
|
||||||
|
|
||||||
|
# 创建与选择框完全一致的碰撞体
|
||||||
|
cBox = CollisionBox(minPoint, maxPoint)
|
||||||
|
cNode.addSolid(cBox)
|
||||||
|
radius = max(maxPoint.x - minPoint.x, maxPoint.y - minPoint.y, maxPoint.z - minPoint.z) / 2
|
||||||
|
else:
|
||||||
|
# 使用默认球体
|
||||||
radius = 1.0
|
radius = 1.0
|
||||||
print(f"⚠️ 模型 {model.getName()} 半径为零,使用默认半径 1.0")
|
cSphere = CollisionSphere(Point3(0, 0, 0), radius)
|
||||||
#
|
cNode.addSolid(cSphere)
|
||||||
# # 添加碰撞球体
|
else:
|
||||||
# cSphere = CollisionSphere(center, radius)
|
# 使用默认球体
|
||||||
cSphere = self.world.collision_manager.createCollisionShape(model, 'polygon')
|
radius = 1.0
|
||||||
|
cSphere = CollisionSphere(Point3(0, 0, 0), radius)
|
||||||
cNode.addSolid(cSphere)
|
cNode.addSolid(cSphere)
|
||||||
|
|
||||||
# 将碰撞节点附加到模型上
|
# 将碰撞节点附加到模型上
|
||||||
cNodePath = model.attachNewNode(cNode)
|
cNodePath = model.attachNewNode(cNode)
|
||||||
|
|
||||||
# 根据调试设置决定是否显示碰撞体
|
# 根据调试设置决定是否显示碰撞体
|
||||||
if hasattr(self.world, 'debug_collision') and self.world.debug_collision:
|
# if hasattr(self.world, 'debug_collision') and self.world.debug_collision:
|
||||||
cNodePath.hide()
|
# cNodePath.show()
|
||||||
else:
|
# else:
|
||||||
cNodePath.hide()
|
# cNodePath.hide()
|
||||||
|
|
||||||
# 为模型添加碰撞相关标签
|
# 为模型添加碰撞相关标签
|
||||||
model.setTag("has_collision", "true")
|
model.setTag("has_collision", "true")
|
||||||
model.setTag("collision_radius", str(radius if 'radius' in locals() else 1.0))
|
model.setTag("collision_radius", str(radius))
|
||||||
|
|
||||||
print(f"✅ 为模型 {model.getName()} 设置碰撞检测完成")
|
print(f"✅ 为模型 {model.getName()} 设置碰撞检测完成")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user