From 0a5fb750fa4b6fe0b039b5f880365ade275b3feb Mon Sep 17 00:00:00 2001 From: hyzboy Date: Thu, 8 Aug 2024 01:43:20 +0800 Subject: [PATCH] create BillboardSceneNode, but isn't final design. --- CMCore | 2 +- CMSceneGraph | 2 +- example/Gizmo/Gizmo3DRotate.cpp | 2 +- example/Gizmo/GizmoTest.cpp | 97 ++++++++++++++++++++--------- example/Gizmo/RayPicking.cpp | 10 +-- example/common/VulkanAppFramework.h | 14 ++--- inc/hgl/graph/SceneNode.h | 9 +++ 7 files changed, 91 insertions(+), 45 deletions(-) diff --git a/CMCore b/CMCore index 1bc9a625..cc4183ca 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 1bc9a625da6689e95a106e838b81dd82e2eb69e8 +Subproject commit cc4183ca55158efa3e4321cc3dbfbd3703eca1d6 diff --git a/CMSceneGraph b/CMSceneGraph index d79ee130..079becd2 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit d79ee130efcc4e4df9a5e0185e41908639490fe4 +Subproject commit 079becd267447676ced6678bd8406208d73169ee diff --git a/example/Gizmo/Gizmo3DRotate.cpp b/example/Gizmo/Gizmo3DRotate.cpp index 6ed4d5f9..e58c90e4 100644 --- a/example/Gizmo/Gizmo3DRotate.cpp +++ b/example/Gizmo/Gizmo3DRotate.cpp @@ -42,7 +42,7 @@ bool InitGizmoRotateStaticMesh() { Transform tm; - tm.SetScale(10.0f); + tm.SetScale(5.0f); root_node->CreateSubNode(tm,torus[0]); diff --git a/example/Gizmo/GizmoTest.cpp b/example/Gizmo/GizmoTest.cpp index 58dbdd2c..d7291017 100644 --- a/example/Gizmo/GizmoTest.cpp +++ b/example/Gizmo/GizmoTest.cpp @@ -8,21 +8,56 @@ using namespace hgl::graph; const Vector3f GizmoPosition(0,0,0); /** -* 求一个世界坐标在屏幕上的位置 +* 一种永远转向正面的场景节点 */ -Vector2f WorldToScreen(const Vector3f &world_pos,const CameraInfo &ci,const ViewportInfo &vi) +class BillboardSceneNode:public SceneNode { - Vector4f pos=ci.vp*Vector4f(world_pos,1); + CameraInfo *camera_info=nullptr; + bool face_to_camera=false; - pos/=pos.w; + ViewportInfo *viewport_info=nullptr; + float fixed_scale=1.0; - return Vector2f((pos.x+1)*vi.GetViewportWidth()/2,(1-pos.y)*vi.GetViewportHeight()/2); -} +public: + + using SceneNode::SceneNode; + virtual ~BillboardSceneNode()=default; + + virtual void SetCameraInfo (CameraInfo * ci ){camera_info =ci;} + virtual void SetViewportInfo(ViewportInfo * vi ){viewport_info =vi;} + + virtual void SetFaceToCamera(bool ftc ){face_to_camera=ftc;} + virtual void SetFixedScale (const float size){fixed_scale =size;} + + virtual bool RefreshTransform(const Transform &tf=IdentityTransform) override + { + if(!camera_info) + { + return SceneNode::RefreshTransform(tf); + } + + if(face_to_camera) + { + LocalTransform.SetRotation(CalculateFacingRotationQuat(GetWorldPosition(),camera_info->view,AxisVector::X)); + } + + if(viewport_info) + { + const float screen_height=viewport_info->GetViewportHeight(); + + const Vector4f pos=camera_info->Project(GetWorldPosition()); + + LocalTransform.SetScale(pos.w*fixed_scale/screen_height); + } + + return SceneNode::RefreshTransform(tf); + } +};//class BillboardSceneNode:public SceneNode class TestApp:public SceneAppFramework { SceneNode root; - SceneNode *rotate_white_torus=nullptr; + BillboardSceneNode *rotate_white_torus=nullptr; StaticMesh *sm_move=nullptr; StaticMesh *sm_rotate=nullptr; @@ -47,22 +82,33 @@ private: void InitGizmoSceneTree() { camera_control->Refresh(); - const CameraInfo &ci=camera_control->GetCameraInfo(); + CameraInfo *ci=camera_control->GetCameraInfo(); root.Clear(); root.CreateSubNode(sm_move->GetScene()); root.CreateSubNode(sm_rotate->GetScene()); - rotate_white_torus=root.CreateSubNode(face_torus); + { + Transform tm; + + tm.SetScale(7.5); + + rotate_white_torus=new BillboardSceneNode(tm,face_torus); + + rotate_white_torus->SetCameraInfo(ci); + rotate_white_torus->SetFaceToCamera(true); + + root.AddSubNode(rotate_white_torus); + } root.RefreshTransform(); - render_list->SetCamera(&(camera_control->GetCameraInfo())); + render_list->SetCamera(ci); render_list->Expend(&root); } public: - + bool Init(uint w,uint h) { if(!SceneAppFramework::Init(w,h)) @@ -71,7 +117,7 @@ public: if(!InitGizmo()) return(false); - InitGizmoSceneTree(); + InitGizmoSceneTree(); camera->pos=Vector3f(32,32,32); camera_control->SetTarget(Vector3f(0,0,0)); @@ -88,29 +134,20 @@ public: { camera_control->Refresh(); - const CameraInfo &ci=camera_control->GetCameraInfo(); - const ViewportInfo &vi=GetViewportInfo(); + const CameraInfo *ci=camera_control->GetCameraInfo(); + const ViewportInfo *vi=GetViewportInfo(); - const float screen_height=vi.GetViewportHeight(); + const float screen_height=vi->GetViewportHeight(); - const Vector4f pos=ci.Project(GizmoPosition); + const Vector4f pos=ci->Project(GizmoPosition); - { - Transform tm; + //{ + // Transform tm; - tm.SetRotation(CalculateFacingRotationQuat(GizmoPosition,ci.view,AxisVector::X)); - tm.SetScale(15); + // tm.SetScale(pos.w*16.0f/screen_height); - rotate_white_torus->SetLocalTransform(tm); - } - - { - Transform tm; - - tm.SetScale(pos.w*16.0f/screen_height); - - root.SetLocalTransform(tm); - } + // root.SetLocalTransform(tm); + //} root.RefreshTransform(); render_list->UpdateTransform(); diff --git a/example/Gizmo/RayPicking.cpp b/example/Gizmo/RayPicking.cpp index 78a9680e..76d457e1 100644 --- a/example/Gizmo/RayPicking.cpp +++ b/example/Gizmo/RayPicking.cpp @@ -55,7 +55,7 @@ private: cfg.local_to_world=true; - { + { cfg.mtl_name="VertexLuminance2D"; //注意必须用不同名字,未来改名材质文件名+cfg hash名 cfg.position_format=VAT_VEC2; @@ -69,7 +69,7 @@ private: mi_plane_grid=db->CreateMaterialInstance(mtl_plane_grid,&vil_config,&white_color); if(!mi_plane_grid)return(false); - pipeline_plane_grid=CreatePipeline(mi_plane_grid,InlinePipeline::Solid3D,Prim::Lines); + pipeline_plane_grid=CreatePipeline(mi_plane_grid,InlinePipeline::Solid3D,Prim::Lines); if(!pipeline_plane_grid)return(false); } @@ -184,10 +184,10 @@ public: void BuildCommandBuffer(uint32 index) override { - const CameraInfo &ci=GetCameraInfo(); - const ViewportInfo &vi=GetViewportInfo(); + const CameraInfo *ci=GetCameraInfo(); + const ViewportInfo *vi=GetViewportInfo(); - ray.Set(GetMouseCoord(),&ci,&vi); //设置射线查询的屏幕坐标点 + ray.Set(GetMouseCoord(),ci,vi); //设置射线查询的屏幕坐标点 const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标 diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index dcbd213c..3a56d1f4 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -173,9 +173,9 @@ public: ubo_vp_info->Write(&vp_info); } - ViewportInfo &GetViewportInfo() + ViewportInfo *GetViewportInfo() { - return vp_info; + return &vp_info; } DeviceBuffer *GetViewportInfoBuffer() @@ -532,9 +532,9 @@ public: win->Join(ckc); win->Join(cmc); - RefreshCameraInfo(&camera_control->GetCameraInfo(),&vp_info,camera); + RefreshCameraInfo(camera_control->GetCameraInfo(),&vp_info,camera); - ubo_camera_info=db->CreateUBO("CameraInfo",sizeof(CameraInfo),&camera_control->GetCameraInfo()); + ubo_camera_info=db->CreateUBO("CameraInfo",sizeof(CameraInfo),camera_control->GetCameraInfo()); } void Resize(uint w,uint h)override @@ -543,10 +543,10 @@ public: camera_control->Refresh(); - ubo_camera_info->Write(&camera_control->GetCameraInfo()); + ubo_camera_info->Write(camera_control->GetCameraInfo()); } - CameraInfo &GetCameraInfo() + CameraInfo *GetCameraInfo() { return camera_control->GetCameraInfo(); } @@ -562,7 +562,7 @@ public: { camera_control->Refresh(); //更新相机矩阵 - ubo_camera_info->Write(&camera_control->GetCameraInfo()); //写入缓冲区 + ubo_camera_info->Write(camera_control->GetCameraInfo()); //写入缓冲区 const uint32_t index=AcquireNextImage(); diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index 02fe4ae9..3ddb2f19 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -55,6 +55,15 @@ namespace hgl Renderable *GetRenderable(){return render_obj;} void SetRenderable(Renderable *); + SceneNode *AddSubNode(SceneNode *sn) + { + if(!sn) + return(nullptr); + + SubNode.Add(sn); + return sn; + } + SceneNode *CreateSubNode() { SceneNode *sn=new SceneNode();