diff --git a/doc/Gizmo.odg b/doc/Gizmo.odg new file mode 100644 index 00000000..f15de8a0 Binary files /dev/null and b/doc/Gizmo.odg differ diff --git a/example/Gizmo/Gizmo3DMove.cpp b/example/Gizmo/Gizmo3DMove.cpp index e69de29b..745f1363 100644 --- a/example/Gizmo/Gizmo3DMove.cpp +++ b/example/Gizmo/Gizmo3DMove.cpp @@ -0,0 +1,234 @@ +// Gizmo 3D Move + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +static Color4f white_color(1,1,1,1); +static Color4f yellow_color(1,1,0,1); + +class TestApp:public SceneAppFramework +{ + Color4f color; + + DeviceBuffer *ubo_color=nullptr; + +private: + + Material * mtl_vtx_lum =nullptr; + MaterialInstance * mi_plane_grid =nullptr; + Pipeline * pipeline_vtx_lum =nullptr; + Primitive * ro_plane_grid =nullptr; + + Material * mtl_vtx_color =nullptr; + MaterialInstance * mi_line =nullptr; + Pipeline * pipeline_vtx_color =nullptr; + Primitive * ro_line =nullptr; + + VBO * vbo_pos =nullptr; + + Ray ray; + +private: + + bool InitMaterialAndPipeline() + { + { + mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",Prim::Lines); + + cfg.local_to_world=true; + + mtl_vtx_lum=db->LoadMaterial("Std3D/VertexLum3D",&cfg); + if(!mtl_vtx_lum)return(false); + + mi_plane_grid=db->CreateMaterialInstance(mtl_vtx_lum,nullptr,&white_color); + if(!mi_plane_grid)return(false); + + pipeline_vtx_lum=CreatePipeline(mtl_vtx_lum,InlinePipeline::Solid3D,Prim::Lines); + + if(!pipeline_vtx_lum) + return(false); + } + + { + mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor3D",Prim::Lines); + + cfg.local_to_world=true; + + mtl_vtx_color=db->LoadMaterial("Std3D/VertexColor3D",&cfg); + if(!mtl_vtx_color)return(false); + + mi_line=db->CreateMaterialInstance(mtl_vtx_color); + if(!mi_line)return(false); + + { + const PipelineData *ipd=GetPipelineData(InlinePipeline::Solid3D); + + if(!ipd) + return(false); + + PipelineData *pd=new PipelineData(ipd); + + pd->SetLineWidth(2); + + pipeline_vtx_color=CreatePipeline(mtl_vtx_color,pd,Prim::Lines); + + delete pd; + + if(!pipeline_vtx_color) + return(false); + } + } + + return(true); + } + + Renderable *Add(Primitive *r,MaterialInstance *mi,Pipeline *p) + { + Renderable *ri=db->CreateRenderable(r,mi,p); + + if(!ri) + { + LOG_ERROR(OS_TEXT("Create Renderable failed.")); + return(nullptr); + } + + render_root.CreateSubNode(ri); + + return ri; + } + + /** + * 写入一个坐标轴的线条数据. + * + * \param pos 要写入数据的指针 + * \param max_line 主线条方向 + * \param oa1 其它轴1方向 + * \param oa2 其它轴2方向 + */ + void WriteAxisPosition(Vector3f *pos,const Vector3f &max_line,const Vector3f &oa1,const Vector3f &oa2) + { + constexpr const float AXIS_LENGTH =4; + constexpr const float AXIS_MIN_STEP =1; + constexpr const float AXIS_ARROW_SIZE=0.25; + + const Vector3f end_pos =max_line*AXIS_LENGTH; ///<最终点位置 + const Vector3f cross_pos=max_line*AXIS_MIN_STEP; ///<坐标轴尾部交叉线位置 + const Vector3f arrow_pos=max_line*(AXIS_LENGTH-AXIS_MIN_STEP); ///<箭头末端在主线上的位置 + + //主线 + pos[0]=Vector3f(0, 0, 0); + pos[1]=end_pos; + + //四根箭头线 + pos[2]=end_pos; + pos[3]=arrow_pos-oa1*AXIS_ARROW_SIZE; + + pos[4]=end_pos; + pos[5]=arrow_pos+oa1*AXIS_ARROW_SIZE; + + pos[6]=end_pos; + pos[7]=arrow_pos-oa2*AXIS_ARROW_SIZE; + + pos[8]=end_pos; + pos[9]=arrow_pos+oa2*AXIS_ARROW_SIZE; + + //侧边连接其它轴线 + pos[10]=cross_pos; + pos[11]=cross_pos+oa1*AXIS_MIN_STEP; + pos[12]=cross_pos; + pos[13]=cross_pos+oa2*AXIS_MIN_STEP; + } + + bool CreateRenderObject() + { + using namespace inline_geometry; + + { + struct PlaneGridCreateInfo pgci; + + pgci.grid_size.width =32; + pgci.grid_size.height=32; + + pgci.sub_count.width =8; + pgci.sub_count.height=8; + + pgci.lum=0.5; + pgci.sub_lum=0.75; + + ro_plane_grid=CreatePlaneGrid(db,mtl_vtx_lum->GetDefaultVIL(),&pgci); + } + + { + constexpr const uint AXIS_MAX_LINES =7; + + ro_line=db->CreatePrimitive("Line",AXIS_MAX_LINES*2*3); + if(!ro_line)return(false); + + Vector3f position_data[3][AXIS_MAX_LINES*2]; + + WriteAxisPosition(position_data[0],Vector3f(1,0,0),Vector3f(0,1,0),Vector3f(0,0,1)); + WriteAxisPosition(position_data[1],Vector3f(0,1,0),Vector3f(1,0,0),Vector3f(0,0,1)); + WriteAxisPosition(position_data[2],Vector3f(0,0,1),Vector3f(1,0,0),Vector3f(0,1,0)); + + Color4f color_data[3][AXIS_MAX_LINES*2]; + + for(Color4f &c:color_data[0])c=Color4f(1,0,0,1); + for(Color4f &c:color_data[1])c=Color4f(0,1,0,1); + for(Color4f &c:color_data[2])c=Color4f(0,0,1,1); + + if(!ro_line->Set(VAN::Position, vbo_pos= db->CreateVBO(VF_V3F,AXIS_MAX_LINES*2*3,position_data)))return(false); + if(!ro_line->Set(VAN::Color, db->CreateVBO(VF_V4F,AXIS_MAX_LINES*2*3,color_data )))return(false); + } + + return(true); + } + + bool InitScene() + { + //Add(ro_plane_grid,mi_plane_grid,pipeline_vtx_lum); + Add(ro_line,mi_line,pipeline_vtx_color); + + camera->pos=Vector3f(32,32,32); + camera_control->SetTarget(Vector3f(0,0,0)); + camera_control->Refresh(); + + render_root.RefreshMatrix(); + render_list->Expend(&render_root); + + return(true); + } + +public: + + bool Init(int w,int h) override + { + if(!SceneAppFramework::Init(w,h)) + return(false); + + if(!InitMaterialAndPipeline()) + return(false); + + if(!CreateRenderObject()) + return(false); + + if(!InitScene()) + return(false); + + return(true); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + return RunApp(1280,720); +}