14 Commits

Author SHA1 Message Date
65bff60f17 大致对了,但由于射线是单向的,所以还需要支持向反方向移动 2025-08-04 01:32:51 +08:00
ed3a4a2eea [BIG OK]差不多效果对了,但是移动比例不对,这个很奇怪! 2025-08-03 23:31:43 +08:00
9db2c4beb6 submodule默认仓库全部改成git.hyzgame.com 2025-08-02 23:07:33 +08:00
64dc1c66d3 [BUG]使用独立TransformTranslate3f来做偏移,此法不能用。变换后会导致矩阵变换,PICK失效。需要另做打算。 2025-08-01 13:58:05 +08:00
28d4d17d62 [working] gizmo3DMove,需要考虑如何绘制变动中的gizmo 2025-08-01 09:13:41 +08:00
d9c0ea3c51 [working] gizmo3d move 2025-07-31 13:48:17 +08:00
95ac4ba973 EventDispatcher派生类返回使用EventProcResult替换bool 2025-07-30 23:21:53 +08:00
51c6c335e7 准备实现gizmo3dmove拖拉 2025-07-29 13:31:08 +08:00
24569ea36f 实现Gizmo3DMove三个轴都可以选 2025-07-29 01:09:53 +08:00
3c611be712 改进Gizmo3DMove的选中判断 2025-07-29 00:44:03 +08:00
eb4a8fba21 增加Gizmo3DMove::DuplicationComponents实现,删除Gizmo::Duplication实现。旧的方法不对,复制了COMPONENT,但记录的是旧的COMPONENT,所以改OVERRIDE MATERIAL无效。 2025-07-28 13:54:44 +08:00
6b86823755 [OK] 已证明新的Ray::ToLineSegmentDistance函数有效,测试成功。但因为没有通知RENDER LIST更新AssignBuffer所以看不出来效果。 2025-07-28 13:28:05 +08:00
cb93ade96f 尝试为Gizmo3DMove::OnMove增加判断逻辑 2025-07-28 00:09:30 +08:00
0b2d3d100a Scene增加RenderFramework属性,SceneNode增加获取RenderFramework功能 2025-07-28 00:09:01 +08:00
12 changed files with 276 additions and 71 deletions

14
.gitmodules vendored
View File

@@ -1,21 +1,21 @@
[submodule "CMCMakeModule"]
path = CMCMakeModule
url = https://github.com/hyzboy/CMCMakeModule
url = http://git.hyzgame.com:3000/hyzboy/CMCMakeModule
[submodule "CMCore"]
path = CMCore
url = https://github.com/hyzboy/CMCore
url = http://git.hyzgame.com:3000/hyzboy/CMCore
[submodule "CMPlatform"]
path = CMPlatform
url = https://github.com/hyzboy/CMPlatform
url = http://git.hyzgame.com:3000/hyzboy/CMPlatform
[submodule "CMAssetsManage"]
path = CMAssetsManage
url = https://github.com/hyzboy/CMAssetsManage.git
url = http://git.hyzgame.com:3000/hyzboy/CMAssetsManage.git
[submodule "res"]
path = res
url = https://github.com/hyzboy/RuntimeData.git
url = http://git.hyzgame.com:3000/hyzboy/RuntimeData.git
[submodule "CMSceneGraph"]
path = CMSceneGraph
url = https://github.com/hyzboy/CMSceneGraph.git
url = http://git.hyzgame.com:3000/hyzboy/CMSceneGraph.git
[submodule "CMUtil"]
path = CMUtil
url = https://github.com/hyzboy/CMUtil.git
url = http://git.hyzgame.com:3000/hyzboy/CMUtil.git

2
CMCore

Submodule CMCore updated: 0ed44f0531...e73191bad7

View File

@@ -26,8 +26,12 @@
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/RenderFramework.h>
#include<hgl/graph/Scene.h>
#include<hgl/component/MeshComponent.h>
#include<hgl/io/event/MouseEvent.h>
#include<hgl/graph/Ray.h>
#include<iostream>
VK_NAMESPACE_BEGIN
@@ -40,14 +44,31 @@ namespace
{
struct GizmoMoveAxis
{
MaterialInstance *mi; //材质实例
MeshComponent *cylinder; //圆柱
MeshComponent *cone; //圆锥
MeshComponent *square; //双轴调节正方形
};
MaterialInstance *pick_mi;
MeshComponent *sphere=nullptr;
GizmoMoveAxis axis[3]{}; //X,Y,Z 三个轴
protected:
Ray MouseRay;
int CurAXIS=-1; //当前鼠标选中轴
float CurDist=0; //当前距离
int PickAXIS=-1; //拾取轴
float PickDist=0; //拾取辆距离轴心的距离
float PickCenterPPU=0; //拾取时的中心点相对屏幕空间象素的缩放比
Matrix4f PickL2W; //拾取时的变换矩阵
Vector3f PickCenter; //拾取时的中心位置
TransformTranslate3f *CurTranslate=nullptr;
public:
using SceneNode::SceneNode;
@@ -62,17 +83,29 @@ namespace
return(new GizmoMoveNode);
}
SceneNode *Duplication()const override
void DuplicationComponents(SceneNode *node) const override
{
GizmoMoveNode *new_gmn=(GizmoMoveNode *)SceneNode::Duplication();
GizmoMoveNode *gmn=(GizmoMoveNode *)node;
if(!new_gmn)
return(nullptr);
if(!gmn)
return;
new_gmn->sphere=sphere;
hgl_cpy(new_gmn->axis,axis);
gmn->pick_mi=pick_mi;
return new_gmn;
#define DUPLICATION_COMPONENT(c) gmn->c=(MeshComponent *)(c->Duplication()); \
gmn->AttachComponent(gmn->c);
DUPLICATION_COMPONENT(sphere);
for(size_t i=0;i<3;i++)
{
gmn->axis[i].mi=axis[i].mi; // 复制材质实例
DUPLICATION_COMPONENT(axis[i].cylinder);
DUPLICATION_COMPONENT(axis[i].cone);
DUPLICATION_COMPONENT(axis[i].square);
}
#undef DUPLICATION_COMPONENT
}
bool CreateGizmoGeometry(RenderFramework *render_framework)
@@ -89,13 +122,14 @@ namespace
CreateComponentInfo cci(this);
pick_mi=GetGizmoMI3D(GizmoColor::Yellow); //获取拾取材质实例
sphere=render_framework->CreateComponent<MeshComponent>(&cci,SpherePtr); //中心球
sphere->SetOverrideMaterial(GetGizmoMI3D(GizmoColor::White)); //白色
{
Transform tm;
GizmoMoveAxis *gma;
MaterialInstance *mi=nullptr;
const Vector3f one_scale(1);
const Vector3f square_scale(2);
@@ -103,78 +137,228 @@ namespace
{
gma=axis+size_t(AXIS::Z);
mi=GetGizmoMI3D(GizmoColor::Blue);
gma->mi=GetGizmoMI3D(GizmoColor::Blue);
tm.SetScale(cylinder_scale);
tm.SetTranslation(0,0,GIZMO_CYLINDER_OFFSET);
cci.mat=tm;
gma->cylinder=render_framework->CreateComponent<MeshComponent>(&cci,CylinderPtr); //Z 向上圆柱
gma->cylinder->SetOverrideMaterial(mi);
gma->cylinder->SetOverrideMaterial(gma->mi);
tm.SetScale(one_scale);
tm.SetTranslation(0,0,GIZMO_CONE_OFFSET);
cci.mat=tm;
gma->cone=render_framework->CreateComponent<MeshComponent>(&cci,ConePtr); //Z 向上圆锥
gma->cone->SetOverrideMaterial(mi);
gma->cone->SetOverrideMaterial(gma->mi);
tm.SetScale(square_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET,0);
cci.mat=tm;
gma->square=render_framework->CreateComponent<MeshComponent>(&cci,SquarePtr);
gma->square->SetOverrideMaterial(mi);
gma->square->SetOverrideMaterial(gma->mi);
}
{
gma=axis+size_t(AXIS::X);
mi=GetGizmoMI3D(GizmoColor::Red);
gma->mi=GetGizmoMI3D(GizmoColor::Red);
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::Y,90);
tm.SetTranslation(GIZMO_CYLINDER_OFFSET,0,0);
cci.mat=tm;
gma->cylinder=render_framework->CreateComponent<MeshComponent>(&cci,CylinderPtr); //X 向右圆柱
gma->cylinder->SetOverrideMaterial(mi);
gma->cylinder->SetOverrideMaterial(gma->mi);
tm.SetScale(one_scale);
tm.SetTranslation(GIZMO_CONE_OFFSET,0,0);
cci.mat=tm;
gma->cone=render_framework->CreateComponent<MeshComponent>(&cci,ConePtr); //Z 向上圆锥
gma->cone->SetOverrideMaterial(mi);
gma->cone->SetOverrideMaterial(gma->mi);
tm.SetScale(square_scale);
tm.SetTranslation(0,GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET);
cci.mat=tm;
gma->square=render_framework->CreateComponent<MeshComponent>(&cci,SquarePtr);
gma->square->SetOverrideMaterial(mi);
gma->square->SetOverrideMaterial(gma->mi);
}
{
gma=axis+size_t(AXIS::Y);
mi=GetGizmoMI3D(GizmoColor::Green);
gma->mi=GetGizmoMI3D(GizmoColor::Green);
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::X,-90);
tm.SetTranslation(0,GIZMO_CYLINDER_OFFSET,0);
cci.mat=tm;
gma->cylinder=render_framework->CreateComponent<MeshComponent>(&cci,CylinderPtr); //X 向右圆柱
gma->cylinder->SetOverrideMaterial(mi);
gma->cylinder->SetOverrideMaterial(gma->mi);
tm.SetScale(one_scale);
tm.SetTranslation(0,GIZMO_CONE_OFFSET,0);
cci.mat=tm;
gma->cone=render_framework->CreateComponent<MeshComponent>(&cci,ConePtr); //Z 向上圆锥
gma->cone->SetOverrideMaterial(mi);
gma->cone->SetOverrideMaterial(gma->mi);
tm.SetScale(square_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,0,GIZMO_TWO_AXIS_OFFSET);
cci.mat=tm;
gma->square=render_framework->CreateComponent<MeshComponent>(&cci,SquarePtr);
gma->square->SetOverrideMaterial(mi);
gma->square->SetOverrideMaterial(gma->mi);
}
}
return(true);
}
io::EventProcResult OnPressed(const Vector2i &mp,io::MouseButton mb) override
{
GizmoMoveNode::OnMove(mp);
if(CurAXIS>=0&&CurAXIS<3)
{
PickAXIS =CurAXIS;
PickDist =CurDist;
PickL2W =GetLocalToWorldMatrix(); //记录拾取时的变换矩阵
PickCenter =TransformPosition(PickL2W,Vector3f(0,0,0)); //记录拾取时的中心位置
if(CurTranslate)
{
CurTranslate->SetOffset(Vector3f(0,0,0));
}
else
{
CurTranslate=GetTransform().AddTranslate(Vector3f(0,0,0));
}
return io::EventProcResult::Break; // 处理完鼠标按下事件,停止进一步处理
}
return io::EventProcResult::Continue;
}
io::EventProcResult OnReleased(const Vector2i &,io::MouseButton mb) override
{
if(CurTranslate)
{
GetTransform().RemoveTransform(CurTranslate);
CurTranslate=nullptr;
}
return io::EventProcResult::Continue;
}
io::EventProcResult OnMoveAtControl(const Vector2i &mouse_coord)
{
CameraControl *cc=GetCameraControl();
if(!cc)
return io::EventProcResult::Continue;
cc->SetMouseRay(&MouseRay,mouse_coord);
const CameraInfo *ci=cc->GetCameraInfo();
Vector3f axis_vector=GetAxisVector(AXIS(PickAXIS)); //取得轴向量
Vector3f end=axis_vector*std::abs(ci->zfar-ci->znear);
end=TransformPosition(PickL2W,end); //将轴的终点转换到世界坐标
Vector3f p_ray,p_ls;
MouseRay.ClosestPoint(
p_ray, // 射线上的点
p_ls, // 线段上的点
PickCenter, // 线段起点
end); // 线段终点
const float cur_ppu=cc->GetPixelPerUnit(p_ls); //求线段上的点相对屏幕空间象素的缩放比
CurDist=glm::length(p_ls-PickCenter);
const float offset=(CurDist/PickCenterPPU)-(PickDist/PickCenterPPU); //计算线段上的点与原点的距离
CurTranslate->SetOffset(axis_vector*offset); //设置偏移量
std::cout<<"PickDist: "<<PickDist<<std::endl;
std::cout<<"CurDist : "<<CurDist<<std::endl;
return io::EventProcResult::Continue;
}
io::EventProcResult OnMove(const Vector2i &mouse_coord) override
{
if(CurTranslate)
{
return OnMoveAtControl(mouse_coord); //已经选中一个轴了
}
CameraControl *cc=GetCameraControl();
if(!cc)
return io::EventProcResult::Continue;
cc->SetMouseRay(&MouseRay,mouse_coord);
const CameraInfo *ci=cc->GetCameraInfo();
const Matrix4f l2w=GetLocalToWorldMatrix();
const Vector3f center=TransformPosition(l2w,Vector3f(0,0,0));
const float center_ppu=cc->GetPixelPerUnit(center); //求原点坐标相对屏幕空间象素的缩放比
Vector3f axis_vector;
Vector3f start;
Vector3f end;
Vector3f p_ray,p_ls;
float dist;
float pixel_per_unit;
MaterialInstance *mi;
CurAXIS=-1;
for(int i=0;i<3;i++)
{
axis_vector=GetAxisVector(AXIS(i)); //取得轴向量
start =TransformPosition(l2w,axis_vector*center_ppu* GIZMO_CENTER_SPHERE_RADIUS); //将轴的起点转换到世界坐标
end =TransformPosition(l2w,axis_vector*std::abs(ci->zfar-ci->znear));
//求射线与线段的最近点
MouseRay.ClosestPoint( p_ray, //射线上的点
p_ls, //线段上的点
start,end); //线段
dist=glm::distance(p_ray,p_ls); //计算射线与线段的距离
//求p_ls坐标相对屏幕空间象素的缩放比
pixel_per_unit=cc->GetPixelPerUnit(p_ls);
if(dist<GIZMO_CYLINDER_RADIUS*pixel_per_unit)
{
mi=pick_mi;
CurAXIS=i;
CurDist=glm::length(p_ls-center)/center_ppu; //计算线段上的点与原点的距离
PickCenterPPU=center_ppu;
}
else
{
mi=axis[i].mi;
}
axis[i].cylinder->SetOverrideMaterial(mi);
axis[i].cone->SetOverrideMaterial(mi);
//std::cout<<"Mouse: "<<mouse_coord.x<<","<<mouse_coord.y<<std::endl;
//std::cout<<"Ray(Ori): "<<MouseRay.origin.x<<","<<MouseRay.origin.y<<","<<MouseRay.origin.z<<")"<<std::endl;
//std::cout<<"Ray(Dir): "<<MouseRay.direction.x<<","<<MouseRay.direction.y<<","<<MouseRay.direction.z<<")"<<std::endl;
//std::cout<<"Distance: "<<dist<<std::endl;
}
if(CurTranslate)
return io::EventProcResult::Break;
return io::EventProcResult::Continue;
}
};//class GizmoMoveNode:public SceneNode
static GizmoMoveNode *sn_gizmo_move=nullptr;

View File

@@ -18,7 +18,7 @@ constexpr const COLOR gizmo_color[size_t(GizmoColor::RANGE_SIZE)]=
COLOR::BlenderAxisGreen,
COLOR::BlenderAxisBlue,
COLOR::BlenderYellow,
COLOR::GoldenYellow,
};
constexpr const float GIZMO_ARROW_LENGTH =10.0f; ///<箭头整体长度

View File

@@ -1,55 +1,50 @@
#ifndef HGL_GRAPH_RENDER_LIST_INCLUDE
#define HGL_GRAPH_RENDER_LIST_INCLUDE
#pragma once
#include<hgl/graph/VK.h>
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/MaterialRenderMap.h>
#include<hgl/graph/VKArrayBuffer.h>
#include<hgl/graph/VKMaterial.h>
namespace hgl
namespace hgl::graph
{
namespace graph
/**
* 渲染对象列表<br>
* 该类会长期保存使用过的材质信息避重新分配造成的时间和空间浪费。如需彻底清空列表请使用Clear()函数
*/
class RenderList
{
/**
* 渲染对象列表<br>
* 该类会长期保存使用过的材质信息避重新分配造成的时间和空间浪费。如需彻底清空列表请使用Clear()函数
*/
class RenderList
{
protected:
protected:
VulkanDevice * device;
VulkanDevice * device;
CameraInfo * camera_info; ///<相机信息
CameraInfo * camera_info; ///<相机信息
uint renderable_count; ///<可渲染对象数量
MaterialRenderMap mrl_map; ///<按材质分类的渲染列表
uint renderable_count; ///<可渲染对象数量
MaterialRenderMap mrl_map; ///<按材质分类的渲染列表
protected:
protected:
virtual bool ExpendNode(SceneNode *);
virtual bool ExpendNode(SceneNode *);
public:
public:
const CameraInfo *GetCameraInfo()const{return camera_info;}
const CameraInfo *GetCameraInfo()const{return camera_info;}
public:
public:
RenderList(VulkanDevice *);
virtual ~RenderList()=default;
RenderList(VulkanDevice *);
virtual ~RenderList()=default;
virtual void SetCameraInfo(CameraInfo *ci){camera_info=ci;} ///<设置相机信息
virtual bool Expend(SceneNode *); ///<展开场景树到渲染列表
virtual void SetCameraInfo(CameraInfo *ci){camera_info=ci;} ///<设置相机信息
virtual bool Expend(SceneNode *); ///<展开场景树到渲染列表
bool IsEmpty()const{return !renderable_count;} ///<是否是空的
bool IsEmpty()const{return !renderable_count;} ///<是否是空的
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
virtual void UpdateLocalToWorld(); ///<更新所有对象的变换数据
virtual void UpdateMaterialInstance(MeshComponent *); ///<有对象互换了材质实例
virtual void UpdateLocalToWorld(); ///<更新所有对象的变换数据
virtual void UpdateMaterialInstance(MeshComponent *); ///<有对象互换了材质实例
virtual void Clear(); ///<彻底清理
};//class RenderList
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_RENDER_LIST_INCLUDE
virtual void Clear(); ///<彻底清理
};//class RenderList
}//namespace hgl::graph

View File

@@ -6,12 +6,16 @@
namespace hgl::graph
{
class RenderFramework;
/**
* 场景管理器<Br>
* 管理一个场景中的所有资源与场景节点
*/
class Scene
{
RenderFramework *render_framework=nullptr; ///<渲染框架
U8String SceneName; ///<场景名称
ObjectList<SceneNode> SceneNodePool; ///<场景节点池
@@ -28,10 +32,17 @@ namespace hgl::graph
SceneNode * GetRootNode (){return root_node;} ///<获取场景根节点
RenderFramework * GetRenderFramework()const
{
return render_framework;
}
public:
Scene()
Scene(RenderFramework *rf)
{
render_framework=rf;
root_node=new SceneNode(this);
}

View File

@@ -18,6 +18,8 @@ namespace hgl::graph
//每个SceneNode都要记录Scene来区分自己属于那个场景
//这个场景可能是一个确实是一个场景也有可能只是一个StaticMesh
class CameraControl;
using SceneNodeID =int64;
using SceneNodeList =ObjectList<SceneNode>;
@@ -59,7 +61,9 @@ namespace hgl::graph
public:
Scene *GetScene()const{ return main_scene; } ///<取得主场景
Scene * GetScene()const{ return main_scene; } ///<取得主场景
RenderFramework * GetRenderFramework()const; ///<取得渲染框架
CameraControl * GetCameraControl()const; ///<取得默认摄像机控制器
const SceneNodeID & GetNodeID ()const { return node_id; } ///<取得节点ID
const SceneNodeName & GetNodeName ()const { return node_name; } ///<取得节点名称

2
res

Submodule res updated: fe8fcabeb5...e1a36d78f0

View File

@@ -134,7 +134,7 @@ bool RenderFramework::Init(uint w,uint h)
render_resource=new RenderResource(device);
OnChangeDefaultScene(new Scene);
OnChangeDefaultScene(new Scene(this));
default_camera=new Camera();
@@ -177,16 +177,16 @@ void RenderFramework::CreateDefaultRenderer()
auto fpcc=new FirstPersonCameraControl(rt->GetViewportInfo(),default_camera,ubo_camera_info);
auto ckc=new CameraKeyboardControl(fpcc);
auto cmc=new CameraMouseControl(fpcc);
//auto cmc=new CameraMouseControl(fpcc);
this->AddChildDispatcher(fpcc);
fpcc->AddChildDispatcher(ckc);
fpcc->AddChildDispatcher(cmc);
//fpcc->AddChildDispatcher(cmc);
default_camera_control=fpcc;
mouse_event=cmc;
//mouse_event=cmc;
}
default_renderer->SetCameraControl(default_camera_control);

View File

@@ -2,9 +2,20 @@
#include<hgl/component/SceneComponent.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/Scene.h>
#include<hgl/graph/RenderFramework.h>
namespace hgl::graph
{
RenderFramework *SceneNode::GetRenderFramework()const
{
return main_scene?main_scene->GetRenderFramework():nullptr;
}
CameraControl *SceneNode::GetCameraControl()const
{
return main_scene?main_scene->GetRenderFramework()->GetDefaultCameraControl():nullptr;
}
//void SceneNode::SetRenderable(Mesh *ri)
//{
// render_obj=ri;