#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace hgl; using namespace hgl::graph; constexpr const COLOR TestColor[]= { COLOR::MozillaCharcoal, COLOR::MozillaSand, COLOR::BlenderAxisRed, COLOR::BlenderAxisGreen, COLOR::BlenderAxisBlue, COLOR::BananaYellow, COLOR::CherryBlossomPink }; constexpr const size_t COLOR_COUNT=sizeof(TestColor)/sizeof(COLOR); class TestApp:public WorkObject { private: struct MaterialData { Material * material = nullptr; const VIL * vil = nullptr; Pipeline * pipeline = nullptr; MaterialInstance * mi[COLOR_COUNT]{}; }; MaterialData solid; MaterialData wire; VertexDataManager * mesh_vdm=nullptr; struct RenderMesh { Primitive *prim; Mesh *mesh; MeshComponentData *data; ComponentDataPtr cdp; MeshComponent *component; public: ~RenderMesh() { cdp.unref(); delete mesh; delete prim; } }; RenderMesh *rm_plane=nullptr, *rm_sphere=nullptr, *rm_cone=nullptr, *rm_cylinder=nullptr, *rm_torus=nullptr, *rm_box=nullptr; private: bool InitMaterialInstance(MaterialData *md) { if(!md) return(false); Color4f color; for(size_t i=0;imi[i]=CreateMaterialInstance(md->material,nullptr,&color); if(!md->mi[i]) return(false); } md->vil=md->material->GetDefaultVIL(); if(!md->vil) return(false); md->pipeline=CreatePipeline(md->material,InlinePipeline::Solid3D); return md->pipeline; } bool InitSolidMDP() { mtl::Material3DCreateConfig cfg(PrimitiveType::Triangles); mtl::MaterialCreateInfo *mci=mtl::CreateGizmo3D(GetDevAttr(),&cfg); if(!mci) return(false); solid.material=CreateMaterial("Gizmo3D",mci); return InitMaterialInstance(&solid); } bool InitWireMDP() { mtl::Material3DCreateConfig cfg(PrimitiveType::Lines); mtl::MaterialCreateInfo *mci=mtl::CreatePureColor3D(GetDevAttr(),&cfg); if(!mci) return(false); wire.material=CreateMaterial("PureColorLine3D",mci); return InitMaterialInstance(&wire); } bool InitVDM() { mesh_vdm=CreateVDM(solid.vil,HGL_SIZE_1MB); if(!mesh_vdm) return(false); return true; } RenderMesh *CreateRenderMesh(Primitive *prim,MaterialData *md,const int color) { if(!prim) return(nullptr); Mesh *mesh=graph::CreateMesh(prim,md->mi[color],md->pipeline); if(!mesh) return nullptr; RenderMesh *rm=new RenderMesh; rm->prim=prim; rm->mesh=mesh; rm->data=new MeshComponentData(mesh); rm->cdp =rm->data; return rm; } bool CreateGeometryMesh() { using namespace inline_geometry; PrimitiveCreater *prim_creater=new PrimitiveCreater(mesh_vdm); if(!prim_creater) return(false); rm_plane=CreateRenderMesh(CreatePlaneSqaure(prim_creater),&solid,0); //Sphere rm_sphere=CreateRenderMesh(CreateSphere(prim_creater,64),&solid,1); //Cone { struct ConeCreateInfo cci; cci.radius =1; //圆锥半径 cci.halfExtend =1; //圆锤一半高度 cci.numberSlices=64; //圆锥底部分割数 cci.numberStacks=4; //圆锥高度分割数 rm_cone=CreateRenderMesh(CreateCone(prim_creater,&cci),&solid,2); } //Cyliner { struct CylinderCreateInfo cci; cci.halfExtend =1.25; //圆柱一半高度 cci.numberSlices=16; //圆柱底部分割数 cci.radius =1.25f; //圆柱半径 rm_cylinder=CreateRenderMesh(CreateCylinder(prim_creater,&cci),&solid,3); } //Torus { struct TorusCreateInfo tci; tci.innerRadius=1.9; tci.outerRadius=2.1; tci.numberSlices=128; tci.numberStacks=16; rm_torus=CreateRenderMesh(CreateTorus(prim_creater,&tci),&solid,4); } delete prim_creater; return(true); } bool CreateBoundingBoxMesh() { using namespace inline_geometry; auto pc=GetPrimitiveCreater(wire.material); inline_geometry::BoundingBoxCreateInfo bbci; rm_box=CreateRenderMesh(CreateBoundingBox(pc,&bbci),&wire,5); return rm_box; } bool InitScene() { CreateComponentInfo cci(GetSceneRoot()); { cci.mat=AxisZRotate(45.0f)*ScaleMatrix(10,10,1); rm_plane->component=CreateComponent(&cci,rm_plane->cdp); } { cci.mat=TranslateMatrix(0,0,0.2)*AxisYRotate(deg2rad(90.0f)); rm_torus->component=CreateComponent(&cci,rm_torus->cdp); rm_torus->component->SetOverrideMaterial(solid.mi[1]); } { cci.mat=TranslateMatrix(0,0,1); rm_cone->component=CreateComponent(&cci,rm_cone->cdp); rm_cone->component->SetOverrideMaterial(solid.mi[2]); } { cci.mat=TranslateMatrix(5,0,3)*AxisRotate(deg2rad(30),20,30,40); rm_cylinder->component=CreateComponent(&cci,rm_cylinder->cdp); rm_cylinder->component->SetOverrideMaterial(solid.mi[3]); } { cci.mat=TranslateMatrix(0,0,4); rm_sphere->component=CreateComponent(&cci,rm_sphere->cdp); rm_sphere->component->SetOverrideMaterial(solid.mi[4]); } return(true); } bool InitBoundingBoxScene() { SceneNode *root=GetSceneRoot(); CreateComponentInfo cci(root); ArrayList box_matrices; for(Component *c:root->GetComponents()) { if(c->GetTypeHash()!=MeshComponent::StaticTypeHash()) continue; MeshComponent *component=(MeshComponent *)c; Matrix4f mat; if(component->GetWorldOBBMatrix(mat)) box_matrices.Add(mat); } //不可以直接在上面的循环中创建新的Component,因为循环本身就要读取Component列表 for(const Matrix4f &mat:box_matrices) { cci.mat=mat; if(!CreateComponent(&cci,rm_box->cdp)) return(false); } return(true); } void SetCamera() { CameraControl *camera_control=GetCameraControl(); camera_control->SetPosition(Vector3f(8,8,8)); camera_control->SetTarget(Vector3f(0,0,0)); } public: using WorkObject::WorkObject; ~TestApp() { SAFE_CLEAR(rm_box) SAFE_CLEAR(rm_torus) SAFE_CLEAR(rm_cylinder) SAFE_CLEAR(rm_cone) SAFE_CLEAR(rm_sphere) SAFE_CLEAR(rm_plane) SAFE_CLEAR(mesh_vdm) } bool Init() override { if(!InitSolidMDP()) return(false); if(!InitWireMDP()) return(false); if(!InitVDM()) return(false); if(!CreateGeometryMesh()) return(false); if(!CreateBoundingBoxMesh()) return(false); if(!InitScene()) return(false); if(!InitBoundingBoxScene()) return(false); SetCamera(); return(true); } };//class TestApp:public CameraAppFramework int os_main(int,os_char **) { return RunFramework(OS_TEXT("Render Bounding Box"),1280,720); }