feat(render): 实现模型部件变换控制面板
- 新增 TransformPanel 类,提供图形界面控制模型部件的位移、旋转、缩放和中心点 - 在 ModelLayerPanelTest 中集成变换面板,支持自动更新选中部件 - 为 ModelPart 添加事件系统,支持变换属性变更通知 - 实现 Mesh2D 的 pivot 和 originalPivot 分离,支持更精确的变换控制- 添加 ModelEvent 接口,用于模型部件事件触发机制 - 优化 ModelRenderPanel 的选中部件获取逻辑 - 完善模型点击监听器,支持自动切换到变换控制选项卡 -修复拖拽移动中心点时的边界检查问题 - 增强各变换操作的边界验证和错误处理 - 改进中心点绘制逻辑,增加边界检查和回退机制 重要更新 - 修复上个版本的所有问题,并且增加新的面板观测图层的各种信息
This commit is contained in:
@@ -3,6 +3,7 @@ package com.chuangzhou.vivid2D.test;
|
||||
import com.chuangzhou.vivid2D.render.awt.ModelClickListener;
|
||||
import com.chuangzhou.vivid2D.render.awt.ModelLayerPanel;
|
||||
import com.chuangzhou.vivid2D.render.awt.ModelRenderPanel;
|
||||
import com.chuangzhou.vivid2D.render.awt.TransformPanel;
|
||||
import com.chuangzhou.vivid2D.render.model.Model2D;
|
||||
import com.chuangzhou.vivid2D.render.model.ModelPart;
|
||||
import com.chuangzhou.vivid2D.render.model.util.Mesh2D;
|
||||
@@ -30,20 +31,13 @@ public class ModelLayerPanelTest {
|
||||
}
|
||||
|
||||
// 创建 UI
|
||||
JFrame frame = new JFrame("ModelLayerPanel 测试(含渲染面板)");
|
||||
JFrame frame = new JFrame("ModelLayerPanel 测试(含渲染面板和变换面板)");
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
frame.setLayout(new BorderLayout());
|
||||
|
||||
// 左侧:图层面板(传入 renderPanel 后可在面板中绑定贴图到 GL 上下文)
|
||||
// 先创建一个占位 renderPanel,再把它传给 layerPanel(ModelRenderPanel 构造需要尺寸)
|
||||
ModelRenderPanel renderPanel = new ModelRenderPanel(model, 640, 480);
|
||||
//renderPanel.addModelClickListener(new ModelClickListener() {
|
||||
// @Override
|
||||
// public void onModelClicked(Mesh2D mesh, float modelX, float modelY, int screenX, int screenY) {
|
||||
// if (mesh == null) return;
|
||||
// System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY);
|
||||
// }
|
||||
//});
|
||||
ModelLayerPanel layerPanel = new ModelLayerPanel(model, renderPanel);
|
||||
layerPanel.setPreferredSize(new Dimension(260, 600));
|
||||
frame.add(layerPanel, BorderLayout.WEST);
|
||||
@@ -52,11 +46,25 @@ public class ModelLayerPanelTest {
|
||||
renderPanel.setPreferredSize(new Dimension(640, 480));
|
||||
frame.add(renderPanel, BorderLayout.CENTER);
|
||||
|
||||
// 右侧:显示模型树(用于观察当前模型部件结构)
|
||||
// 创建变换面板
|
||||
TransformPanel transformPanel = new TransformPanel(renderPanel);
|
||||
|
||||
// 右侧:创建选项卡面板,包含模型树和变换面板
|
||||
JTabbedPane rightTabbedPane = new JTabbedPane();
|
||||
|
||||
// 模型树选项卡
|
||||
JTree tree = new JTree(model.toTreeNode());
|
||||
JScrollPane treeScroll = new JScrollPane(tree);
|
||||
treeScroll.setPreferredSize(new Dimension(240, 600));
|
||||
frame.add(treeScroll, BorderLayout.EAST);
|
||||
treeScroll.setPreferredSize(new Dimension(280, 600));
|
||||
rightTabbedPane.addTab("模型结构", treeScroll);
|
||||
|
||||
// 变换面板选项卡
|
||||
JScrollPane transformScroll = new JScrollPane(transformPanel);
|
||||
transformScroll.setPreferredSize(new Dimension(280, 600));
|
||||
rightTabbedPane.addTab("变换控制", transformScroll);
|
||||
|
||||
rightTabbedPane.setPreferredSize(new Dimension(300, 600));
|
||||
frame.add(rightTabbedPane, BorderLayout.EAST);
|
||||
|
||||
// 底部:演示按钮(刷新树以反映面板中对模型的更改)
|
||||
JPanel bottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
@@ -80,8 +88,39 @@ public class ModelLayerPanelTest {
|
||||
});
|
||||
bottom.add(printOrderBtn);
|
||||
|
||||
// 添加选中部件更新按钮
|
||||
JButton updateSelectionBtn = new JButton("更新选中部件");
|
||||
updateSelectionBtn.addActionListener(e -> {
|
||||
renderPanel.executeInGLContext(() -> {
|
||||
ModelPart selectedPart = renderPanel.getSelectedPart();
|
||||
transformPanel.setSelectedPart(selectedPart);
|
||||
if (selectedPart != null) {
|
||||
System.out.println("已选中部件: " + selectedPart.getName());
|
||||
} else {
|
||||
System.out.println("未选中任何部件");
|
||||
}
|
||||
});
|
||||
});
|
||||
bottom.add(updateSelectionBtn);
|
||||
|
||||
frame.add(bottom, BorderLayout.SOUTH);
|
||||
|
||||
// 添加模型点击监听器,自动更新变换面板的选中部件
|
||||
renderPanel.addModelClickListener(new ModelClickListener() {
|
||||
@Override
|
||||
public void onModelClicked(Mesh2D mesh, float modelX, float modelY, int screenX, int screenY) {
|
||||
if (mesh == null) return;
|
||||
System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY);
|
||||
|
||||
// 自动更新变换面板的选中部件
|
||||
ModelPart selectedPart = renderPanel.getSelectedPart();
|
||||
transformPanel.setSelectedPart(selectedPart);
|
||||
|
||||
// 切换到变换控制选项卡
|
||||
rightTabbedPane.setSelectedIndex(1);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听窗口关闭,确保释放 GL 资源
|
||||
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
@Override
|
||||
@@ -104,9 +143,9 @@ public class ModelLayerPanelTest {
|
||||
}
|
||||
});
|
||||
|
||||
frame.setSize(1200, 700);
|
||||
frame.setSize(1300, 700);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user