diff --git a/inc/hgl/graph/VKPrimitive.h b/inc/hgl/graph/VKPrimitive.h index eab2d294..cd5f92dc 100644 --- a/inc/hgl/graph/VKPrimitive.h +++ b/inc/hgl/graph/VKPrimitive.h @@ -28,6 +28,12 @@ public: Primitive(const AnsiString &pn,PrimitiveData *pd); virtual ~Primitive(); + void SetBoundingBox(const AABB &bb) { bounding_box=bb; } ///<设置包围盒 + void SetBoundingBox(const Vector3f &box_min,const Vector3f &box_max) + { + bounding_box.SetMinMax(box_min,box_max); + } + public: const AnsiString & GetName ()const{ return prim_name; } diff --git a/src/SceneGraph/InlineGeometry.cpp b/src/SceneGraph/InlineGeometry.cpp index 0085b7af..68c4dabc 100644 --- a/src/SceneGraph/InlineGeometry.cpp +++ b/src/SceneGraph/InlineGeometry.cpp @@ -7,1470 +7,1531 @@ #include #include -namespace hgl +namespace hgl::graph::inline_geometry { - namespace graph + Primitive *CreateRectangle(PrimitiveCreater *pc,const RectangleCreateInfo *rci) { - namespace inline_geometry + if(!pc)return(nullptr); + + if(!pc->Init("Rectangle",4,0)) + return(nullptr); + + VABMap2f vertex(pc->GetVABMap(VAN::Position)); + + if(!vertex.IsValid()) + return(nullptr); + + vertex->WriteRectFan(rci->scope); + + return pc->Create(); + } + + Primitive *CreateGBufferCompositionRectangle(PrimitiveCreater *pc) + { + RectangleCreateInfo rci; + + rci.scope.Set(-1,-1,2,2); + + return CreateRectangle(pc,&rci); + } + + Primitive *CreateRoundRectangle(PrimitiveCreater *pc,const RoundRectangleCreateInfo *rci) + { + if(!pc)return(nullptr); + + if(rci->radius==0||rci->round_per<=1) //这是要画矩形 { - Primitive *CreateRectangle(PrimitiveCreater *pc,const RectangleCreateInfo *rci) - { - if(!pc)return(nullptr); - - if(!pc->Init("Rectangle",4,0)) - return(nullptr); - - VABMap2f vertex(pc->GetVABMap(VAN::Position)); - - if(!vertex.IsValid()) - return(nullptr); - - vertex->WriteRectFan(rci->scope); - - return pc->Create(); - } - - Primitive *CreateGBufferCompositionRectangle(PrimitiveCreater *pc) - { - RectangleCreateInfo rci; - - rci.scope.Set(-1,-1,2,2); - - return CreateRectangle(pc,&rci); - } - - Primitive *CreateRoundRectangle(PrimitiveCreater *pc,const RoundRectangleCreateInfo *rci) - { - if(!pc)return(nullptr); - - if(rci->radius==0||rci->round_per<=1) //这是要画矩形 - { - if(!pc->Init("RoundRectangle",4,0)) - return(nullptr); + if(!pc->Init("RoundRectangle",4,0)) + return(nullptr); - VABMap2f vertex(pc->GetVABMap(VAN::Position)); + VABMap2f vertex(pc->GetVABMap(VAN::Position)); - vertex->WriteRectFan(rci->scope); - } - else - { - float radius=rci->radius; + vertex->WriteRectFan(rci->scope); + } + else + { + float radius=rci->radius; - if(radius>rci->scope.GetWidth()/2.0f)radius=rci->scope.GetWidth()/2.0f; - if(radius>rci->scope.GetHeight()/2.0f)radius=rci->scope.GetHeight()/2.0f; + if(radius>rci->scope.GetWidth()/2.0f)radius=rci->scope.GetWidth()/2.0f; + if(radius>rci->scope.GetHeight()/2.0f)radius=rci->scope.GetHeight()/2.0f; - if(!pc->Init("RoundRectangle",rci->round_per*4,8)) - return(nullptr); + if(!pc->Init("RoundRectangle",rci->round_per*4,8)) + return(nullptr); - VABMap2f vertex(pc->GetVABMap(VAN::Position)); + VABMap2f vertex(pc->GetVABMap(VAN::Position)); - Vector2f *coord=new Vector2f[rci->round_per]; + Vector2f *coord=new Vector2f[rci->round_per]; - float l=rci->scope.GetLeft(), - r=rci->scope.GetRight(), - t=rci->scope.GetTop(), - b=rci->scope.GetBottom(); + float l=rci->scope.GetLeft(), + r=rci->scope.GetRight(), + t=rci->scope.GetTop(), + b=rci->scope.GetBottom(); - for(uint i=0;iround_per;i++) - { - float ang=float(i)/float(rci->round_per-1)*90.0f; + for(uint i=0;iround_per;i++) + { + float ang=float(i)/float(rci->round_per-1)*90.0f; - float x=sin(deg2rad(ang))*radius; - float y=cos(deg2rad(ang))*radius; + float x=sin(deg2rad(ang))*radius; + float y=cos(deg2rad(ang))*radius; - coord[i].x=x; - coord[i].y=y; + coord[i].x=x; + coord[i].y=y; - //右上角 - vertex->Write(r-radius+x, - t+radius-y); - } - - //右下角 - for(uint i=0;iround_per;i++) - { - vertex->Write(r-radius+coord[rci->round_per-1-i].x, - b-radius+coord[rci->round_per-1-i].y); - } - - //左下角 - for(uint i=0;iround_per;i++) - { - vertex->Write(l+radius-coord[i].x, - b-radius+coord[i].y); - } - - //左上角 - for(uint i=0;iround_per;i++) - { - vertex->Write(l+radius-coord[rci->round_per-1-i].x, - t+radius-coord[rci->round_per-1-i].y); - } - - delete[] coord; - } - - return pc->Create(); + //右上角 + vertex->Write(r-radius+x, + t+radius-y); } - Primitive *CreateCircle2D(PrimitiveCreater *pc,const CircleCreateInfo *cci) + //右下角 + for(uint i=0;iround_per;i++) { - if(!pc)return(nullptr); + vertex->Write(r-radius+coord[rci->round_per-1-i].x, + b-radius+coord[rci->round_per-1-i].y); + } - uint edge; - uint vertex_count; + //左下角 + for(uint i=0;iround_per;i++) + { + vertex->Write(l+radius-coord[i].x, + b-radius+coord[i].y); + } - if(cci->has_center) - { - edge=cci->field_count+1; - vertex_count=cci->field_count+2; - } - else - { - edge=cci->field_count; - vertex_count=cci->field_count; - } + //左上角 + for(uint i=0;iround_per;i++) + { + vertex->Write(l+radius-coord[rci->round_per-1-i].x, + t+radius-coord[rci->round_per-1-i].y); + } - if(!pc->Init("Circle",vertex_count,0))return(nullptr); + delete[] coord; + } - VABMap2f vertex(pc->GetVABMap(VAN::Position)); - VABMap4f color(pc->GetVABMap(VAN::Color)); + return pc->Create(); + } - if(!vertex.IsValid()) - return(nullptr); + Primitive *CreateCircle2D(PrimitiveCreater *pc,const CircleCreateInfo *cci) + { + if(!pc)return(nullptr); - if(cci->has_center) - { - vertex->Write(cci->center); + uint edge; + uint vertex_count; - if(color.IsValid()) - color->Write(cci->center_color); - } + if(cci->has_center) + { + edge=cci->field_count+1; + vertex_count=cci->field_count+2; + } + else + { + edge=cci->field_count; + vertex_count=cci->field_count; + } - for(uint i=0;ifield_count)*360.0f; + if(!pc->Init("Circle",vertex_count,0))return(nullptr); - float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; - float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; + VABMap2f vertex(pc->GetVABMap(VAN::Position)); + VABMap4f color(pc->GetVABMap(VAN::Color)); - vertex->Write(x,y); + if(!vertex.IsValid()) + return(nullptr); + + if(cci->has_center) + { + vertex->Write(cci->center); + + if(color.IsValid()) + color->Write(cci->center_color); + } + + for(uint i=0;ifield_count)*360.0f; + + float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; + float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; + + vertex->Write(x,y); - if(color.IsValid()) - color->Write(cci->border_color); - } + if(color.IsValid()) + color->Write(cci->border_color); + } - return pc->Create(); - } + return pc->Create(); + } - template - void WriteIBO(T *p,const T start,const T count) - { - for(T i=start;i + void WriteIBO(T *p,const T start,const T count) + { + for(T i=start;ihas_center) - { - edge=cci->field_count+1; - vertex_count=cci->field_count+2; - } - else - { - edge=cci->field_count; - vertex_count=cci->field_count; - } + if(cci->has_center) + { + edge=cci->field_count+1; + vertex_count=cci->field_count+2; + } + else + { + edge=cci->field_count; + vertex_count=cci->field_count; + } - bool has_index=pc->hasIndex(); + bool has_index=pc->hasIndex(); - if(!pc->Init("Circle",vertex_count,has_index?vertex_count:0))return(nullptr); + if(!pc->Init("Circle",vertex_count,has_index?vertex_count:0))return(nullptr); - VABMap3f vertex(pc->GetVABMap(VAN::Position)); - VABMap4f color(pc->GetVABMap(VAN::Color)); - VABMap3f normal(pc->GetVABMap(VAN::Normal)); + VABMap3f vertex(pc->GetVABMap(VAN::Position)); + VABMap4f color(pc->GetVABMap(VAN::Color)); + VABMap3f normal(pc->GetVABMap(VAN::Normal)); - if(!vertex.IsValid()) - return(nullptr); + if(!vertex.IsValid()) + return(nullptr); - if(cci->has_center) - { - vertex->Write(cci->center.x,cci->center.y,0); + if(cci->has_center) + { + vertex->Write(cci->center.x,cci->center.y,0); - if(color.IsValid()) - color->Write(cci->center_color); + if(color.IsValid()) + color->Write(cci->center_color); - if(normal.IsValid()) - normal->Write(AxisVector::Z); - } + if(normal.IsValid()) + normal->Write(AxisVector::Z); + } - for(uint i=0;ifield_count)*360.0f; + for(uint i=0;ifield_count)*360.0f; - float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; - float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; + float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; + float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; - vertex->Write(x,y,0); + vertex->Write(x,y,0); - if(color.IsValid()) - color->Write(cci->border_color); + if(color.IsValid()) + color->Write(cci->border_color); - if(normal.IsValid()) - normal->Write(AxisVector::Z); - } + if(normal.IsValid()) + normal->Write(AxisVector::Z); + } - if(has_index) - { - IBMap *ib_map=pc->GetIBMap(); + if(has_index) + { + IBMap *ib_map=pc->GetIBMap(); - if(pc->GetIndexType()==IndexType::U16)WriteIBO((uint16 *)(ib_map->Map()),0,vertex_count);else - if(pc->GetIndexType()==IndexType::U32)WriteIBO((uint32 *)(ib_map->Map()),0,vertex_count);else - if(pc->GetIndexType()==IndexType::U8 )WriteIBO((uint8 *)(ib_map->Map()),0,vertex_count); + if(pc->GetIndexType()==IndexType::U16)WriteIBO((uint16 *)(ib_map->Map()),0,vertex_count);else + if(pc->GetIndexType()==IndexType::U32)WriteIBO((uint32 *)(ib_map->Map()),0,vertex_count);else + if(pc->GetIndexType()==IndexType::U8 )WriteIBO((uint8 *)(ib_map->Map()),0,vertex_count); - ib_map->Unmap(); - } + ib_map->Unmap(); + } - return pc->Create(); - } + return pc->Create(); + } - template - void WriteCircleIBO(T *ibo,const uint edge_count) - { - T *p=ibo; + template + void WriteCircleIBO(T *ibo,const uint edge_count) + { + T *p=ibo; - for(T i=1;ifield_count; - index_count=(vertex_count-2)*3; + vertex_count=cci->field_count; + index_count=(vertex_count-2)*3; - if(!pc->Init("Circle",vertex_count,index_count))return(nullptr); + if(!pc->Init("Circle",vertex_count,index_count))return(nullptr); - VABMap3f vertex(pc->GetVABMap(VAN::Position)); - VABMap4f color(pc->GetVABMap(VAN::Color)); - VABMap3f normal(pc->GetVABMap(VAN::Normal)); + VABMap3f vertex(pc->GetVABMap(VAN::Position)); + VABMap4f color(pc->GetVABMap(VAN::Color)); + VABMap3f normal(pc->GetVABMap(VAN::Normal)); - if(!vertex.IsValid()) - return(nullptr); + if(!vertex.IsValid()) + return(nullptr); - for(uint i=0;ifield_count+1;i++) - { - float ang=float(i)/float(cci->field_count)*360.0f; + for(uint i=0;ifield_count+1;i++) + { + float ang=float(i)/float(cci->field_count)*360.0f; - float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; - float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; + float x=cci->center.x+sin(deg2rad(ang))*cci->radius.x; + float y=cci->center.y+cos(deg2rad(ang))*cci->radius.y; - vertex->Write(x,y,0); + vertex->Write(x,y,0); - if(color.IsValid()) - color->Write(cci->border_color); + if(color.IsValid()) + color->Write(cci->border_color); - if(normal.IsValid()) - normal->Write(AxisVector::Z); - } + if(normal.IsValid()) + normal->Write(AxisVector::Z); + } - { - IBMap *ib_map=pc->GetIBMap(); + { + IBMap *ib_map=pc->GetIBMap(); - if(pc->GetIndexType()==IndexType::U16)WriteCircleIBO((uint16 *)(ib_map->Map()),cci->field_count);else - if(pc->GetIndexType()==IndexType::U32)WriteCircleIBO((uint32 *)(ib_map->Map()),cci->field_count);else - if(pc->GetIndexType()==IndexType::U8 )WriteCircleIBO((uint8 *)(ib_map->Map()),cci->field_count); + if(pc->GetIndexType()==IndexType::U16)WriteCircleIBO((uint16 *)(ib_map->Map()),cci->field_count);else + if(pc->GetIndexType()==IndexType::U32)WriteCircleIBO((uint32 *)(ib_map->Map()),cci->field_count);else + if(pc->GetIndexType()==IndexType::U8 )WriteCircleIBO((uint8 *)(ib_map->Map()),cci->field_count); - ib_map->Unmap(); - } + ib_map->Unmap(); + } - return pc->Create(); - } + return pc->Create(); + } - Primitive *CreatePlaneGrid2D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci) + Primitive *CreatePlaneGrid2D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci) + { + if(!pc->Init("PlaneGrid",((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0)) + return(nullptr); + + VABMap2f vertex(pc->GetVABMap(VAN::Position)); + + if(!vertex.IsValid()) + return(nullptr); + + const float right=float(pgci->grid_size.Width())/2.0f; + const float left =-right; + + const float bottom=float(pgci->grid_size.Height())/2.0f; + const float top =-bottom; + + for(uint row=0;row<=pgci->grid_size.Height();row++) + { + vertex->WriteLine( Vector2f(left ,top+row), + Vector2f(right,top+row)); + } + + for(uint col=0;col<=pgci->grid_size.Width();col++) + { + vertex->WriteLine(Vector2f(left+col,top ), + Vector2f(left+col,bottom)); + } + + VABMap1uf8 lum(pc->GetVABMap(VAN::Luminance)); + + if(lum.IsValid()) + { + for(uint row=0;row<=pgci->grid_size.Height();row++) { - if(!pc->Init("PlaneGrid",((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0)) - return(nullptr); - - VABMap2f vertex(pc->GetVABMap(VAN::Position)); - - if(!vertex.IsValid()) - return(nullptr); - - const float right=float(pgci->grid_size.Width())/2.0f; - const float left =-right; - - const float bottom=float(pgci->grid_size.Height())/2.0f; - const float top =-bottom; - - for(uint row=0;row<=pgci->grid_size.Height();row++) - { - vertex->WriteLine( Vector2f(left ,top+row), - Vector2f(right,top+row)); - } - - for(uint col=0;col<=pgci->grid_size.Width();col++) - { - vertex->WriteLine(Vector2f(left+col,top ), - Vector2f(left+col,bottom)); - } - - VABMap1uf8 lum(pc->GetVABMap(VAN::Luminance)); - - if(lum.IsValid()) - { - for(uint row=0;row<=pgci->grid_size.Height();row++) - { - if((row%pgci->sub_count.Height())==0) - lum->RepeatWrite(pgci->sub_lum,2); - else - lum->RepeatWrite(pgci->lum,2); - } - - for(uint col=0;col<=pgci->grid_size.Width();col++) - { - if((col%pgci->sub_count.Width())==0) - lum->RepeatWrite(pgci->sub_lum,2); - else - lum->RepeatWrite(pgci->lum,2); - } - } - - return pc->Create(); + if((row%pgci->sub_count.Height())==0) + lum->RepeatWrite(pgci->sub_lum,2); + else + lum->RepeatWrite(pgci->lum,2); } - Primitive *CreatePlaneGrid3D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci) + for(uint col=0;col<=pgci->grid_size.Width();col++) { - if(!pc->Init("PlaneGrid",((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0)) - return(nullptr); + if((col%pgci->sub_count.Width())==0) + lum->RepeatWrite(pgci->sub_lum,2); + else + lum->RepeatWrite(pgci->lum,2); + } + } - VABMap3f vertex(pc->GetVABMap(VAN::Position)); + return pc->Create(); + } - if(!vertex.IsValid()) - return(nullptr); + Primitive *CreatePlaneGrid3D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci) + { + if(!pc->Init("PlaneGrid",((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0)) + return(nullptr); - const float right=float(pgci->grid_size.Width())/2.0f; - const float left =-right; + VABMap3f vertex(pc->GetVABMap(VAN::Position)); - const float bottom=float(pgci->grid_size.Height())/2.0f; - const float top =-bottom; + if(!vertex.IsValid()) + return(nullptr); - for(uint row=0;row<=pgci->grid_size.Height();row++) - { - vertex->WriteLine( Vector3f(left ,top+row,0), - Vector3f(right,top+row,0)); - } + const float right=float(pgci->grid_size.Width())/2.0f; + const float left =-right; - for(uint col=0;col<=pgci->grid_size.Width();col++) - { - vertex->WriteLine(Vector3f(left+col,top ,0), - Vector3f(left+col,bottom,0)); - } + const float bottom=float(pgci->grid_size.Height())/2.0f; + const float top =-bottom; - VABMap1uf8 lum(pc->GetVABMap(VAN::Luminance)); + for(uint row=0;row<=pgci->grid_size.Height();row++) + { + vertex->WriteLine( Vector3f(left ,top+row,0), + Vector3f(right,top+row,0)); + } - if(lum.IsValid()) - { - for(uint row=0;row<=pgci->grid_size.Height();row++) - { - if((row%pgci->sub_count.Height())==0) - lum->RepeatWrite(pgci->sub_lum,2); - else - lum->RepeatWrite(pgci->lum,2); - } + for(uint col=0;col<=pgci->grid_size.Width();col++) + { + vertex->WriteLine(Vector3f(left+col,top ,0), + Vector3f(left+col,bottom,0)); + } - for(uint col=0;col<=pgci->grid_size.Width();col++) - { - if((col%pgci->sub_count.Width())==0) - lum->RepeatWrite(pgci->sub_lum,2); - else - lum->RepeatWrite(pgci->lum,2); - } - } + VABMap1uf8 lum(pc->GetVABMap(VAN::Luminance)); - return pc->Create(); + if(lum.IsValid()) + { + for(uint row=0;row<=pgci->grid_size.Height();row++) + { + if((row%pgci->sub_count.Height())==0) + lum->RepeatWrite(pgci->sub_lum,2); + else + lum->RepeatWrite(pgci->lum,2); } - Primitive *CreatePlaneSqaure(PrimitiveCreater *pc) + for(uint col=0;col<=pgci->grid_size.Width();col++) { - const float xy_vertices [] = { -0.5f,-0.5f,0.0f, +0.5f,-0.5f,0.0f, +0.5f,+0.5f,0.0f, -0.5f,+0.5f,0.0f }; - float xy_tex_coord[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - const Vector3f xy_normal(0.0f,0.0f,1.0f); - const Vector3f xy_tangent(1.0f,0.0f,0.0f); - const uint16 indices[]={0,1,2,0,2,3}; - - if(!pc)return(nullptr); - - if(!pc->Init("Plane",4,6,IndexType::U16)) - return(nullptr); - - if(!pc->WriteVAB(VAN::Position,VF_V3F,xy_vertices)) - return(nullptr); - - { - VABMap3f normal(pc->GetVABMap(VAN::Normal)); - - if(normal.IsValid()) - normal->RepeatWrite(xy_normal,4); - } - - { - VABMap3f tangent(pc->GetVABMap(VAN::Tangent)); - - if(tangent.IsValid()) - tangent->RepeatWrite(xy_tangent,4); - } - - { - VABMap2f tex_coord(pc->GetVABMap(VAN::TexCoord)); - - if(tex_coord.IsValid()) - tex_coord->Write(xy_tex_coord,4); - } - - pc->WriteIBO(indices); - - return pc->Create(); + if((col%pgci->sub_count.Width())==0) + lum->RepeatWrite(pgci->sub_lum,2); + else + lum->RepeatWrite(pgci->lum,2); } + } - Primitive *CreateCube(PrimitiveCreater *pc,const CubeCreateInfo *cci) - { - /** - * 4 5 - * *------------* Z Y - * /| /| | Y | Z - * 0/ | 1/ | | / | / - * *--+---------* | | / | / - * | | | | | / | / - * | 7| | 6| |/ |/ - * | *---------+--* *-----------X *-----------X - * | / | / - * |/ 2|/ my Cubemap - * 3*------------* - * - * 注:cubemap纹理坐标系依然遵循OpenGL时代定下的坐标系,所以这里的position虽然使用vulkan坐标系,但在shader中当做cubemap纹理坐标使用时,需要在shader中转换为opengl坐标系(交换yz即可) - */ + return pc->Create(); + } - constexpr float positions[]={ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, - -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, - -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, - -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, +0.5f, - -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, - +0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f}; + Primitive *CreatePlaneSqaure(PrimitiveCreater *pc) + { + const float xy_vertices [] = { -0.5f,-0.5f,0.0f, +0.5f,-0.5f,0.0f, +0.5f,+0.5f,0.0f, -0.5f,+0.5f,0.0f }; + float xy_tex_coord[] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; + const Vector3f xy_normal(0.0f,0.0f,1.0f); + const Vector3f xy_tangent(1.0f,0.0f,0.0f); + const uint16 indices[]={0,1,2,0,2,3}; - constexpr float normals[]={ +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, - +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, - +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, - +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, - -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, - +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f}; + if(!pc)return(nullptr); - constexpr float tangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, - +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, - -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, - 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, - 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f}; + if(!pc->Init("Plane",4,6,IndexType::U16)) + return(nullptr); - constexpr float tex_coords[] ={ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; - // The associated indices. - constexpr uint16 indices[]={ 0, 2, 1, 0, 3, 2, - 4, 5, 6, 4, 6, 7, - 8, 9, 10, 8, 10, 11, - 12, 15, 14, 12, 14, 13, - 16, 17, 18, 16, 18, 19, - 20, 23, 22, 20, 22, 21}; + if(!pc->WriteVAB(VAN::Position,VF_V3F,xy_vertices)) + return(nullptr); - if(!pc)return(nullptr); + { + VABMap3f normal(pc->GetVABMap(VAN::Normal)); - if(!pc->Init("Cube",24,6*2*3,IndexType::U16)) - return(nullptr); + if(normal.IsValid()) + normal->RepeatWrite(xy_normal,4); + } - if(!pc->WriteVAB(VAN::Position,VF_V3F,positions)) - return(nullptr); + { + VABMap3f tangent(pc->GetVABMap(VAN::Tangent)); - if(cci->normal) - if(!pc->WriteVAB(VAN::Normal,VF_V3F,normals)) - return(nullptr); + if(tangent.IsValid()) + tangent->RepeatWrite(xy_tangent,4); + } - if(cci->tangent) - if(!pc->WriteVAB(VAN::Tangent,VF_V3F,tangents)) - return(nullptr); + { + VABMap2f tex_coord(pc->GetVABMap(VAN::TexCoord)); - if(cci->tex_coord) - if(!pc->WriteVAB(VAN::TexCoord,VF_V2F,tex_coords)) - return(nullptr); + if(tex_coord.IsValid()) + tex_coord->Write(xy_tex_coord,4); + } - if(cci->color_type!=CubeCreateInfo::ColorType::NoColor) - { - RANGE_CHECK_RETURN_NULLPTR(cci->color_type); + pc->WriteIBO(indices); - VABMap4f color(pc->GetVABMap(VAN::Color)); + Primitive *p=pc->Create(); - if(color.IsValid()) - { - if(cci->color_type==CubeCreateInfo::ColorType::SameColor) - color->RepeatWrite(cci->color[0],24); - else - if(cci->color_type==CubeCreateInfo::ColorType::FaceColor) - { - for(uint face=0;face<6;face++) - color->RepeatWrite(cci->color[face],4); - } - else - if(cci->color_type==CubeCreateInfo::ColorType::VertexColor) - color->Write(cci->color,24); - else - return(nullptr); - } - } + { + AABB aabb; - //pc->CreateIBO16(6*2*3,indices); - pc->WriteIBO(indices); - return pc->Create(); - } + aabb.SetMinMax(Vector3f(-0.5f,-0.5f,0.0f),Vector3f(0.5f,0.5f,0.0f)); - template - void CreateSphereIndices(PrimitiveCreater *pc,uint numberParallels,const uint numberSlices) - { - IBTypeMap ib_map(pc->GetIBMap()); - T *tp=ib_map; + p->SetBoundingBox(aabb); + } - for (uint i = 0; i < numberParallels; i++) - { - for (uint j = 0; j < numberSlices; j++) - { - *tp= i * (numberSlices + 1) + j; ++tp; - *tp=(i + 1) * (numberSlices + 1) + (j + 1); ++tp; - *tp=(i + 1) * (numberSlices + 1) + j; ++tp; + return p; + } - *tp= i * (numberSlices + 1) + j; ++tp; - *tp= i * (numberSlices + 1) + (j + 1); ++tp; - *tp=(i + 1) * (numberSlices + 1) + (j + 1); ++tp; - } - } - } - - namespace - { - constexpr uint GLUS_VERTICES_FACTOR =4; - constexpr uint GLUS_VERTICES_DIVISOR=4; - constexpr uint GLUS_MAX_VERTICES =1048576; - constexpr uint GLUS_MAX_INDICES =GLUS_MAX_VERTICES*GLUS_VERTICES_FACTOR; - - void glusQuaternionRotateRyf(float quaternion[4], const float angle) - { - float halfAngleRadian = deg2rad(angle) * 0.5f; - - quaternion[0] = 0.0f; - quaternion[1] = sin(halfAngleRadian); - quaternion[2] = 0.0f; - quaternion[3] = cos(halfAngleRadian); - } - - void glusQuaternionRotateRzf(float quaternion[4], const float angle) - { - float halfAngleRadian = deg2rad(angle) * 0.5f; - - quaternion[0] = 0.0f; - quaternion[1] = 0.0f; - quaternion[2] = sin(halfAngleRadian); - quaternion[3] = cos(halfAngleRadian); - } - - void glusQuaternionGetMatrix4x4f(float matrix[16], const float quaternion[4]) - { - float x = quaternion[0]; - float y = quaternion[1]; - float z = quaternion[2]; - float w = quaternion[3]; - - matrix[0] = 1.0f - 2.0f * y * y - 2.0f * z * z; - matrix[1] = 2.0f * x * y + 2.0f * w * z; - matrix[2] = 2.0f * x * z - 2.0f * w * y; - matrix[3] = 0.0f; - - matrix[4] = 2.0f * x * y - 2.0f * w * z; - matrix[5] = 1.0f - 2.0f * x * x - 2.0f * z * z; - matrix[6] = 2.0f * y * z + 2.0f * w * x; - matrix[7] = 0.0f; - - matrix[8] = 2.0f * x * z + 2.0f * w * y; - matrix[9] = 2.0f * y * z - 2.0f * w * x; - matrix[10] = 1.0f - 2.0f * x * x - 2.0f * y * y; - matrix[11] = 0.0f; - - matrix[12] = 0.0f; - matrix[13] = 0.0f; - matrix[14] = 0.0f; - matrix[15] = 1.0f; - } - - void glusMatrix4x4MultiplyVector3f(float result[3], const float matrix[16], const float vector[3]) - { - int i; - - float temp[3]; - - for (i = 0; i < 3; i++) - { - temp[i] = matrix[i] * vector[0] + matrix[4 + i] * vector[1] + matrix[8 + i] * vector[2]; - } - - for (i = 0; i < 3; i++) - { - result[i] = temp[i]; - } - } - }//namespace - - /** - * 创建一个球体的可渲染数据,球心为0,0,0,半径为1 - * @param numberSlices 切片数 - * @return 可渲染数据 + Primitive *CreateCube(PrimitiveCreater *pc,const CubeCreateInfo *cci) + { + /** + * 4 5 + * *------------* Z Y + * /| /| | Y | Z + * 0/ | 1/ | | / | / + * *--+---------* | | / | / + * | | | | | / | / + * | 7| | 6| |/ |/ + * | *---------+--* *-----------X *-----------X + * | / | / + * |/ 2|/ my Cubemap + * 3*------------* + * + * 注:cubemap纹理坐标系依然遵循OpenGL时代定下的坐标系,所以这里的position虽然使用vulkan坐标系,但在shader中当做cubemap纹理坐标使用时,需要在shader中转换为opengl坐标系(交换yz即可) */ - Primitive *CreateSphere(PrimitiveCreater *pc,const uint numberSlices) + + constexpr float positions[]={ -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, -0.5f, + -0.5f, +0.5f, -0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f, +0.5f, + -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, -0.5f, +0.5f, -0.5f, + +0.5f, -0.5f, -0.5f, +0.5f, -0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, +0.5f, -0.5f}; + + constexpr float normals[]={ +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, +0.0f, +1.0f, +0.0f, + +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, +0.0f, -1.0f, +0.0f, + +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, +0.0f, -0.0f, -1.0f, + +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, +0.0f, -0.0f, +1.0f, + -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, -1.0f, -0.0f, +0.0f, + +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f, +1.0f, -0.0f, +0.0f}; + + constexpr float tangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, + 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, 0.0f, 0.0f,+1.0f, + 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f,-1.0f}; + + constexpr float tex_coords[] ={ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}; + // The associated indices. + constexpr uint16 indices[]={ 0, 2, 1, 0, 3, 2, + 4, 5, 6, 4, 6, 7, + 8, 9, 10, 8, 10, 11, + 12, 15, 14, 12, 14, 13, + 16, 17, 18, 16, 18, 19, + 20, 23, 22, 20, 22, 21}; + + if(!pc)return(nullptr); + + if(!pc->Init("Cube",24,6*2*3,IndexType::U16)) + return(nullptr); + + if(!pc->WriteVAB(VAN::Position,VF_V3F,positions)) + return(nullptr); + + if(cci->normal) + if(!pc->WriteVAB(VAN::Normal,VF_V3F,normals)) + return(nullptr); + + if(cci->tangent) + if(!pc->WriteVAB(VAN::Tangent,VF_V3F,tangents)) + return(nullptr); + + if(cci->tex_coord) + if(!pc->WriteVAB(VAN::TexCoord,VF_V2F,tex_coords)) + return(nullptr); + + if(cci->color_type!=CubeCreateInfo::ColorType::NoColor) + { + RANGE_CHECK_RETURN_NULLPTR(cci->color_type); + + VABMap4f color(pc->GetVABMap(VAN::Color)); + + if(color.IsValid()) { - uint numberParallels = (numberSlices+1) / 2; - uint numberVertices = (numberParallels + 1) * (numberSlices + 1); - uint numberIndices = numberParallels * numberSlices * 6; - - const double angleStep = double(2.0f * HGL_PI) / ((double) numberSlices); - - // used later to help us calculating tangents vectors - float helpVector[3] = { 1.0f, 0.0f, 0.0f }; - float helpQuaternion[4]; - float helpMatrix[16]; - float tex_x; - - if(!pc->Init("Sphere",numberVertices,numberIndices)) - return(nullptr); - - VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); - VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); - VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); - VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); - - float *vp=vertex; - float *np=normal; - float *tp=tangent; - float *tcp=tex_coord; - - if(!vp) - return(nullptr); - - for (uint i = 0; i < numberParallels + 1; i++) + if(cci->color_type==CubeCreateInfo::ColorType::SameColor) + color->RepeatWrite(cci->color[0],24); + else + if(cci->color_type==CubeCreateInfo::ColorType::FaceColor) { - for (uint j = 0; j < numberSlices + 1; j++) - { - float x = sin(angleStep * (double) i) * sin(angleStep * (double) j); - float y = sin(angleStep * (double) i) * cos(angleStep * (double) j); - float z = cos(angleStep * (double) i); - - *vp=x;++vp; - *vp=y;++vp; - *vp=z;++vp; - - if(np) - { - *np=x;++np; - *np=y;++np; - *np=z;++np; - } - - if(tcp) - { - tex_x=(float) j / (float) numberSlices; - - *tcp=tex_x;++tcp; - *tcp=1.0f - (float) i / (float) numberParallels;++tcp; - - if(tp) - { - // use quaternion to get the tangent vector - glusQuaternionRotateRyf(helpQuaternion, 360.0f * tex_x); - glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); - - glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); - tp+=3; - } - } - } + for(uint face=0;face<6;face++) + color->RepeatWrite(cci->color[face],4); } + else + if(cci->color_type==CubeCreateInfo::ColorType::VertexColor) + color->Write(cci->color,24); + else + return(nullptr); + } + } - //索引 - { - const IndexType index_type=pc->GetIndexType(); + pc->WriteIBO(indices); - if(index_type==IndexType::U16)CreateSphereIndices(pc,numberParallels,numberSlices);else - if(index_type==IndexType::U32)CreateSphereIndices(pc,numberParallels,numberSlices);else - if(index_type==IndexType::U8 )CreateSphereIndices(pc,numberParallels,numberSlices);else - return(nullptr); - } + Primitive *p=pc->Create(); - return pc->Create(); + p->SetBoundingBox(Vector3f(-0.5f,-0.5f,-0.5f),Vector3f(0.5f,0.5f,0.5f)); + + return p; + } + + template + void CreateSphereIndices(PrimitiveCreater *pc,uint numberParallels,const uint numberSlices) + { + IBTypeMap ib_map(pc->GetIBMap()); + T *tp=ib_map; + + for (uint i = 0; i < numberParallels; i++) + { + for (uint j = 0; j < numberSlices; j++) + { + *tp= i * (numberSlices + 1) + j; ++tp; + *tp=(i + 1) * (numberSlices + 1) + (j + 1); ++tp; + *tp=(i + 1) * (numberSlices + 1) + j; ++tp; + + *tp= i * (numberSlices + 1) + j; ++tp; + *tp= i * (numberSlices + 1) + (j + 1); ++tp; + *tp=(i + 1) * (numberSlices + 1) + (j + 1); ++tp; + } + } + } + + namespace + { + constexpr uint GLUS_VERTICES_FACTOR =4; + constexpr uint GLUS_VERTICES_DIVISOR=4; + constexpr uint GLUS_MAX_VERTICES =1048576; + constexpr uint GLUS_MAX_INDICES =GLUS_MAX_VERTICES*GLUS_VERTICES_FACTOR; + + void glusQuaternionRotateRyf(float quaternion[4], const float angle) + { + float halfAngleRadian = deg2rad(angle) * 0.5f; + + quaternion[0] = 0.0f; + quaternion[1] = sin(halfAngleRadian); + quaternion[2] = 0.0f; + quaternion[3] = cos(halfAngleRadian); + } + + void glusQuaternionRotateRzf(float quaternion[4], const float angle) + { + float halfAngleRadian = deg2rad(angle) * 0.5f; + + quaternion[0] = 0.0f; + quaternion[1] = 0.0f; + quaternion[2] = sin(halfAngleRadian); + quaternion[3] = cos(halfAngleRadian); + } + + void glusQuaternionGetMatrix4x4f(float matrix[16], const float quaternion[4]) + { + float x = quaternion[0]; + float y = quaternion[1]; + float z = quaternion[2]; + float w = quaternion[3]; + + matrix[0] = 1.0f - 2.0f * y * y - 2.0f * z * z; + matrix[1] = 2.0f * x * y + 2.0f * w * z; + matrix[2] = 2.0f * x * z - 2.0f * w * y; + matrix[3] = 0.0f; + + matrix[4] = 2.0f * x * y - 2.0f * w * z; + matrix[5] = 1.0f - 2.0f * x * x - 2.0f * z * z; + matrix[6] = 2.0f * y * z + 2.0f * w * x; + matrix[7] = 0.0f; + + matrix[8] = 2.0f * x * z + 2.0f * w * y; + matrix[9] = 2.0f * y * z - 2.0f * w * x; + matrix[10] = 1.0f - 2.0f * x * x - 2.0f * y * y; + matrix[11] = 0.0f; + + matrix[12] = 0.0f; + matrix[13] = 0.0f; + matrix[14] = 0.0f; + matrix[15] = 1.0f; + } + + void glusMatrix4x4MultiplyVector3f(float result[3], const float matrix[16], const float vector[3]) + { + int i; + + float temp[3]; + + for (i = 0; i < 3; i++) + { + temp[i] = matrix[i] * vector[0] + matrix[4 + i] * vector[1] + matrix[8 + i] * vector[2]; } - Primitive *CreateDome(PrimitiveCreater *pc,const uint numberSlices) + for (i = 0; i < 3; i++) { - if(!pc)return(nullptr); + result[i] = temp[i]; + } + } + }//namespace - uint i, j; + /** + * 创建一个球体的可渲染数据,球心为0,0,0,半径为1 + * @param numberSlices 切片数 + * @return 可渲染数据 + */ + Primitive *CreateSphere(PrimitiveCreater *pc,const uint numberSlices) + { + uint numberParallels = (numberSlices+1) / 2; + uint numberVertices = (numberParallels + 1) * (numberSlices + 1); + uint numberIndices = numberParallels * numberSlices * 6; - uint numberParallels = numberSlices / 4; - uint numberVertices = (numberParallels + 1) * (numberSlices + 1); - uint numberIndices = numberParallels * numberSlices * 6; + const double angleStep = double(2.0f * HGL_PI) / ((double) numberSlices); - float angleStep = (2.0f * HGL_PI) / ((float) numberSlices); + // used later to help us calculating tangents vectors + float helpVector[3] = { 1.0f, 0.0f, 0.0f }; + float helpQuaternion[4]; + float helpMatrix[16]; + float tex_x; - // used later to help us calculating tangents vectors - float helpVector[3] = { 1.0f, 0.0f, 0.0f }; - float helpQuaternion[4]; - float helpMatrix[16]; - float tex_x; + if(!pc->Init("Sphere",numberVertices,numberIndices)) + return(nullptr); - if (numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) - return nullptr; + VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); + VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); + VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); + VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); - if(!pc->Init("Dome",numberVertices,numberIndices)) - return(nullptr); - - VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); - VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); - VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); - VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); + float *vp=vertex; + float *np=normal; + float *tp=tangent; + float *tcp=tex_coord; - float *vp=vertex; - float *np=normal; - float *tp=tangent; - float *tcp=tex_coord; + if(!vp) + return(nullptr); - if(!vp) - return(nullptr); + for (uint i = 0; i < numberParallels + 1; i++) + { + for (uint j = 0; j < numberSlices + 1; j++) + { + float x = sin(angleStep * (double) i) * sin(angleStep * (double) j); + float y = sin(angleStep * (double) i) * cos(angleStep * (double) j); + float z = cos(angleStep * (double) i); - for (i = 0; i < numberParallels + 1; i++) + *vp=x;++vp; + *vp=y;++vp; + *vp=z;++vp; + + if(np) { - for (j = 0; j < numberSlices + 1; j++) + *np=x;++np; + *np=y;++np; + *np=z;++np; + } + + if(tcp) + { + tex_x=(float) j / (float) numberSlices; + + *tcp=tex_x;++tcp; + *tcp=1.0f - (float) i / (float) numberParallels;++tcp; + + if(tp) { - uint vertexIndex = (i * (numberSlices + 1) + j) * 4; - uint normalIndex = (i * (numberSlices + 1) + j) * 3; - uint tangentIndex = (i * (numberSlices + 1) + j) * 3; - uint texCoordsIndex = (i * (numberSlices + 1) + j) * 2; + // use quaternion to get the tangent vector + glusQuaternionRotateRyf(helpQuaternion, 360.0f * tex_x); + glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); + + glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); + tp+=3; + } + } + } + } + + //索引 + { + const IndexType index_type=pc->GetIndexType(); + + if(index_type==IndexType::U16)CreateSphereIndices(pc,numberParallels,numberSlices);else + if(index_type==IndexType::U32)CreateSphereIndices(pc,numberParallels,numberSlices);else + if(index_type==IndexType::U8 )CreateSphereIndices(pc,numberParallels,numberSlices);else + return(nullptr); + } + + Primitive *p=pc->Create(); + + { + AABB aabb; + aabb.SetMinMax(Vector3f(-1.0f,-1.0f,-1.0f),Vector3f(1.0f,1.0f,1.0f)); + p->SetBoundingBox(aabb); + } + + return p; + } + + Primitive *CreateDome(PrimitiveCreater *pc,const uint numberSlices) + { + if(!pc)return(nullptr); + + uint i, j; + + uint numberParallels = numberSlices / 4; + uint numberVertices = (numberParallels + 1) * (numberSlices + 1); + uint numberIndices = numberParallels * numberSlices * 6; + + float angleStep = (2.0f * HGL_PI) / ((float) numberSlices); + + // used later to help us calculating tangents vectors + float helpVector[3] = { 1.0f, 0.0f, 0.0f }; + float helpQuaternion[4]; + float helpMatrix[16]; + float tex_x; + + if (numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) + return nullptr; + + if(!pc->Init("Dome",numberVertices,numberIndices)) + return(nullptr); + + VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); + VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); + VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); + VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); + + float *vp=vertex; + float *np=normal; + float *tp=tangent; + float *tcp=tex_coord; + + if(!vp) + return(nullptr); + + for (i = 0; i < numberParallels + 1; i++) + { + for (j = 0; j < numberSlices + 1; j++) + { + uint vertexIndex = (i * (numberSlices + 1) + j) * 4; + uint normalIndex = (i * (numberSlices + 1) + j) * 3; + uint tangentIndex = (i * (numberSlices + 1) + j) * 3; + uint texCoordsIndex = (i * (numberSlices + 1) + j) * 2; - float x = sin(angleStep * (double) i) * sin(angleStep * (double) j); - float y = sin(angleStep * (double) i) * cos(angleStep * (double) j); - float z = cos(angleStep * (double) i); + float x = sin(angleStep * (double) i) * sin(angleStep * (double) j); + float y = sin(angleStep * (double) i) * cos(angleStep * (double) j); + float z = cos(angleStep * (double) i); - *vp=x;++vp; - *vp=y;++vp; - *vp=z;++vp; - - if(np) - { - *np=+x;++np; - *np=-y;++np; - *np=+z;++np; - } - - if(tcp) - { - tex_x=(float) j / (float) numberSlices; - - *tcp=tex_x;++tcp; - *tcp=1.0f - (float) i / (float) numberParallels;++tcp; - - if(tp) - { - // use quaternion to get the tangent vector - glusQuaternionRotateRyf(helpQuaternion, 360.0f * tex_x); - glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); - - glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); - tp+=3; - } - } - } - } - - //索引 - { - const IndexType index_type=pc->GetIndexType(); - - if(index_type==IndexType::U16)CreateSphereIndices(pc,numberParallels,numberSlices);else - if(index_type==IndexType::U32)CreateSphereIndices(pc,numberParallels,numberSlices);else - if(index_type==IndexType::U8 )CreateSphereIndices(pc,numberParallels,numberSlices);else - return(nullptr); - } - - return pc->Create(); - } - - namespace - { - template - void CreateTorusIndices(PrimitiveCreater *pc,uint numberSlices,uint numberStacks) - { - IBTypeMap ib_map(pc->GetIBMap()); - T *tp=ib_map; - - // loop counters - uint sideCount, faceCount; - - // used to generate the indices - uint v0, v1, v2, v3; - - for (sideCount = 0; sideCount < numberSlices; ++sideCount) - { - for (faceCount = 0; faceCount < numberStacks; ++faceCount) - { - // get the number of the vertices for a face of the torus. They must be < numVertices - v0 = ((sideCount * (numberStacks + 1)) + faceCount); - v1 = (((sideCount + 1) * (numberStacks + 1)) + faceCount); - v2 = (((sideCount + 1) * (numberStacks + 1)) + (faceCount + 1)); - v3 = ((sideCount * (numberStacks + 1)) + (faceCount + 1)); - - // first triangle of the face, counter clock wise winding - *tp = v0; ++tp; - *tp = v2; ++tp; - *tp = v1; ++tp; - - // second triangle of the face, counter clock wise winding - *tp = v0; ++tp; - *tp = v3; ++tp; - *tp = v2; ++tp; - } - } - } - }//namespace - - Primitive *CreateTorus(PrimitiveCreater *pc,const TorusCreateInfo *tci) - { - if(!pc)return(nullptr); - - // s, t = parametric values of the equations, in the range [0,1] - float s = 0; - float t = 0; - - // sIncr, tIncr are increment values aplied to s and t on each loop iteration to generate the torus - float sIncr; - float tIncr; - - // to store precomputed sin and cos values - float cos2PIs, sin2PIs, cos2PIt, sin2PIt; - - uint sideCount,faceCount; - - uint numberVertices; - uint numberIndices; - - // used later to help us calculating tangents vectors - float helpVector[3] = { 0.0f, 1.0f, 0.0f }; - float helpQuaternion[4]; - float helpMatrix[16]; - - float torusRadius = (tci->outerRadius - tci->innerRadius) / 2.0f; - float centerRadius = tci->outerRadius - torusRadius; - - numberVertices = (tci->numberStacks + 1) * (tci->numberSlices + 1); - numberIndices = tci->numberStacks * tci->numberSlices * 2 * 3; // 2 triangles per face * 3 indices per triangle - - if (tci->numberSlices < 3 || tci->numberStacks < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) - return(nullptr); - - sIncr = 1.0f / (float) tci->numberSlices; - tIncr = 1.0f / (float) tci->numberStacks; - - if(!pc->Init("Torus",numberVertices,numberIndices)) - return(nullptr); - - VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); - VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); - VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); - VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); - - float *vp=vertex; - float *np=normal; - float *tp=tangent; - float *tcp=tex_coord; - - if(!vp) - return(nullptr); - - // generate vertices and its attributes - for (sideCount = 0; sideCount <= tci->numberSlices; ++sideCount, s += sIncr) - { - // precompute some values - cos2PIs = cos(2.0f * HGL_PI * s); - sin2PIs = sin(2.0f * HGL_PI * s); - - t = 0.0f; - for (faceCount = 0; faceCount <= tci->numberStacks; ++faceCount, t += tIncr) - { - // precompute some values - cos2PIt = cos(2.0f * HGL_PI * t); - sin2PIt = sin(2.0f * HGL_PI * t); - - // generate vertex and stores it in the right position - *vp = torusRadius * sin2PIt; ++vp; - *vp =-(centerRadius + torusRadius * cos2PIt) * cos2PIs; ++vp; - *vp = (centerRadius + torusRadius * cos2PIt) * sin2PIs; ++vp; - - if(np) - { - // generate normal and stores it in the right position - // NOTE: cos (2PIx) = cos (x) and sin (2PIx) = sin (x) so, we can use this formula - // normal = {cos(2PIs)cos(2PIt) , sin(2PIs)cos(2PIt) ,sin(2PIt)} - *np = sin2PIt; ++np; - *np = -cos2PIs * cos2PIt; ++np; - *np = sin2PIs * cos2PIt; ++np; - } - - if(tcp) - { - // generate texture coordinates and stores it in the right position - *tcp = s*tci->uv_scale.x; ++tcp; - *tcp = t*tci->uv_scale.y; ++tcp; - } - - if(tp) - { - // use quaternion to get the tangent vector - glusQuaternionRotateRzf(helpQuaternion, 360.0f * s); - glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); - - glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); - tp+=3; - } - } - } - - //索引 - { - const IndexType index_type=pc->GetIndexType(); - - if(index_type==IndexType::U16)CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else - if(index_type==IndexType::U32)CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else - if(index_type==IndexType::U8 )CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else - return(nullptr); - } - return pc->Create(); - } - - namespace - { - template - void CreateCylinderIndices(PrimitiveCreater *pc,const uint numberSlices) - { - IBTypeMap ib_map(pc->GetIBMap()); - T *tp=ib_map; - uint i; - - T centerIndex = 0; - T indexCounter = 1; - - for (i = 0; i < numberSlices; i++) - { - *tp = centerIndex; ++tp; - *tp = indexCounter; ++tp; - *tp = indexCounter + 1; ++tp; - - indexCounter++; - } - indexCounter++; - - // Top - centerIndex = indexCounter; - indexCounter++; - - for (i = 0; i < numberSlices; i++) - { - *tp = centerIndex; ++tp; - *tp = indexCounter + 1; ++tp; - *tp = indexCounter; ++tp; - - indexCounter++; - } - indexCounter++; - - // Sides - for (i = 0; i < numberSlices; i++) - { - *tp = indexCounter; ++tp; - *tp = indexCounter + 1; ++tp; - *tp = indexCounter + 2; ++tp; - - *tp = indexCounter + 2; ++tp; - *tp = indexCounter + 1; ++tp; - *tp = indexCounter + 3; ++tp; - - indexCounter += 2; - } - } - }//namespace - - Primitive *CreateCylinder(PrimitiveCreater *pc,const CylinderCreateInfo *cci) - { - uint numberIndices = cci->numberSlices * 3 * 2 + cci->numberSlices * 6; - - if(numberIndices<=0) - return(nullptr); - - uint numberVertices = (cci->numberSlices + 2) * 2 + (cci->numberSlices + 1) * 2; - - if(!pc->Init("Cylinder",numberVertices,numberIndices)) - return(nullptr); - - float angleStep = (2.0f * HGL_PI) / ((float) cci->numberSlices); - - if (cci->numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) - return nullptr; - - VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); - VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); - VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); - VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); - - float *vp=vertex; - float *np=normal; - float *tp=tangent; - float *tcp=tex_coord; - - if(!vp) - return(nullptr); - - *vp = 0.0f; ++vp; - *vp = 0.0f; ++vp; - *vp = -cci->halfExtend; ++vp; + *vp=x;++vp; + *vp=y;++vp; + *vp=z;++vp; if(np) { - *np = 0.0f; ++np; - *np = 0.0f; ++np; - *np =-1.0f; ++np; + *np=+x;++np; + *np=-y;++np; + *np=+z;++np; } - if(tp) + if(tcp) + { + tex_x=(float) j / (float) numberSlices; + + *tcp=tex_x;++tcp; + *tcp=1.0f - (float) i / (float) numberParallels;++tcp; + + if(tp) + { + // use quaternion to get the tangent vector + glusQuaternionRotateRyf(helpQuaternion, 360.0f * tex_x); + glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); + + glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); + tp+=3; + } + } + } + } + + //索引 + { + const IndexType index_type=pc->GetIndexType(); + + if(index_type==IndexType::U16)CreateSphereIndices(pc,numberParallels,numberSlices);else + if(index_type==IndexType::U32)CreateSphereIndices(pc,numberParallels,numberSlices);else + if(index_type==IndexType::U8 )CreateSphereIndices(pc,numberParallels,numberSlices);else + return(nullptr); + } + + Primitive *p=pc->Create(); + + { + AABB box; + + box.SetMinMax(Vector3f(-1.0f,-1.0f,-1.0f),Vector3f(1.0f,1.0f,1.0f)); //这个不对,待查 + + p->SetBoundingBox(box); + } + + return p; + } + + namespace + { + template + void CreateTorusIndices(PrimitiveCreater *pc,uint numberSlices,uint numberStacks) + { + IBTypeMap ib_map(pc->GetIBMap()); + T *tp=ib_map; + + // loop counters + uint sideCount, faceCount; + + // used to generate the indices + uint v0, v1, v2, v3; + + for (sideCount = 0; sideCount < numberSlices; ++sideCount) + { + for (faceCount = 0; faceCount < numberStacks; ++faceCount) { - *tp = 0.0f; ++tp; - *tp = 1.0f; ++tp; - *tp = 0.0f; ++tp; + // get the number of the vertices for a face of the torus. They must be < numVertices + v0 = ((sideCount * (numberStacks + 1)) + faceCount); + v1 = (((sideCount + 1) * (numberStacks + 1)) + faceCount); + v2 = (((sideCount + 1) * (numberStacks + 1)) + (faceCount + 1)); + v3 = ((sideCount * (numberStacks + 1)) + (faceCount + 1)); + + // first triangle of the face, counter clock wise winding + *tp = v0; ++tp; + *tp = v2; ++tp; + *tp = v1; ++tp; + + // second triangle of the face, counter clock wise winding + *tp = v0; ++tp; + *tp = v3; ++tp; + *tp = v2; ++tp; + } + } + } + }//namespace + + Primitive *CreateTorus(PrimitiveCreater *pc,const TorusCreateInfo *tci) + { + if(!pc)return(nullptr); + + // s, t = parametric values of the equations, in the range [0,1] + float s = 0; + float t = 0; + + // sIncr, tIncr are increment values aplied to s and t on each loop iteration to generate the torus + float sIncr; + float tIncr; + + // to store precomputed sin and cos values + float cos2PIs, sin2PIs, cos2PIt, sin2PIt; + + uint sideCount,faceCount; + + uint numberVertices; + uint numberIndices; + + // used later to help us calculating tangents vectors + float helpVector[3] = { 0.0f, 1.0f, 0.0f }; + float helpQuaternion[4]; + float helpMatrix[16]; + + float torusRadius = (tci->outerRadius - tci->innerRadius) / 2.0f; + float centerRadius = tci->outerRadius - torusRadius; + + numberVertices = (tci->numberStacks + 1) * (tci->numberSlices + 1); + numberIndices = tci->numberStacks * tci->numberSlices * 2 * 3; // 2 triangles per face * 3 indices per triangle + + if (tci->numberSlices < 3 || tci->numberStacks < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) + return(nullptr); + + sIncr = 1.0f / (float) tci->numberSlices; + tIncr = 1.0f / (float) tci->numberStacks; + + if(!pc->Init("Torus",numberVertices,numberIndices)) + return(nullptr); + + VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); + VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); + VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); + VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); + + float *vp=vertex; + float *np=normal; + float *tp=tangent; + float *tcp=tex_coord; + + if(!vp) + return(nullptr); + + // generate vertices and its attributes + for (sideCount = 0; sideCount <= tci->numberSlices; ++sideCount, s += sIncr) + { + // precompute some values + cos2PIs = cos(2.0f * HGL_PI * s); + sin2PIs = sin(2.0f * HGL_PI * s); + + t = 0.0f; + for (faceCount = 0; faceCount <= tci->numberStacks; ++faceCount, t += tIncr) + { + // precompute some values + cos2PIt = cos(2.0f * HGL_PI * t); + sin2PIt = sin(2.0f * HGL_PI * t); + + // generate vertex and stores it in the right position + *vp = torusRadius * sin2PIt; ++vp; + *vp =-(centerRadius + torusRadius * cos2PIt) * cos2PIs; ++vp; + *vp = (centerRadius + torusRadius * cos2PIt) * sin2PIs; ++vp; + + if(np) + { + // generate normal and stores it in the right position + // NOTE: cos (2PIx) = cos (x) and sin (2PIx) = sin (x) so, we can use this formula + // normal = {cos(2PIs)cos(2PIt) , sin(2PIs)cos(2PIt) ,sin(2PIt)} + *np = sin2PIt; ++np; + *np = -cos2PIs * cos2PIt; ++np; + *np = sin2PIs * cos2PIt; ++np; } if(tcp) { - *tcp = 0.0f; ++tcp; - *tcp = 0.0f; ++tcp; - } - - for(uint i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; - - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = -cci->halfExtend; ++vp; - - if(np) - { - *np = 0.0f; ++np; - *np = 0.0f; ++np; - *np =-1.0f; ++np; - } - - if(tp) - { - *tp = sin(currentAngle); ++tp; - *tp = cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; - } - - if(tcp) - { - *tcp = 0.0f; ++tcp; - *tcp = 0.0f; ++tcp; - } - } - - *vp = 0.0f; ++vp; - *vp = 0.0f; ++vp; - *vp = cci->halfExtend; ++vp; - - if(np) - { - *np = 0.0f; ++np; - *np = 0.0f; ++np; - *np = 1.0f; ++np; + // generate texture coordinates and stores it in the right position + *tcp = s*tci->uv_scale.x; ++tcp; + *tcp = t*tci->uv_scale.y; ++tcp; } if(tp) { - *tp = 0.0f; ++tp; - *tp = -1.0f; ++tp; - *tp = 0.0f; ++tp; + // use quaternion to get the tangent vector + glusQuaternionRotateRzf(helpQuaternion, 360.0f * s); + glusQuaternionGetMatrix4x4f(helpMatrix, helpQuaternion); + + glusMatrix4x4MultiplyVector3f(tp, helpMatrix, helpVector); + tp+=3; } - - if(tcp) - { - *tcp = 1.0f; ++tcp; - *tcp = 1.0f; ++tcp; - } - - for(uint i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; - - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = cci->halfExtend; ++vp; - - if(np) - { - *np = 0.0f; ++np; - *np = 0.0f; ++np; - *np = 1.0f; ++np; - } - - if(tp) - { - *tp = -sin(currentAngle); ++tp; - *tp = -cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; - } - - if(tcp) - { - *tcp = 1.0f; ++tcp; - *tcp = 1.0f; ++tcp; - } - } - - for(uint i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; - - float sign = -1.0f; - - for (uint j = 0; j < 2; j++) - { - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = cci->halfExtend * sign; ++vp; - - if(np) - { - *np = cos(currentAngle); ++np; - *np = -sin(currentAngle); ++np; - *np = 0.0f; ++np; - } - - if(tp) - { - *tp = -sin(currentAngle); ++tp; - *tp = -cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; - } - - if(tcp) - { - *tcp = (float)i / (float)cci->numberSlices; ++tcp; - *tcp = (sign + 1.0f) / 2.0f; ++tcp; - } - - sign = 1.0f; - } - } - - //索引 - { - const IndexType index_type=pc->GetIndexType(); - - if(index_type==IndexType::U16)CreateCylinderIndices(pc,cci->numberSlices);else - if(index_type==IndexType::U32)CreateCylinderIndices(pc,cci->numberSlices);else - if(index_type==IndexType::U8 )CreateCylinderIndices(pc,cci->numberSlices);else - return(nullptr); - } - - return pc->Create(); } + } - namespace + //索引 + { + const IndexType index_type=pc->GetIndexType(); + + if(index_type==IndexType::U16)CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else + if(index_type==IndexType::U32)CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else + if(index_type==IndexType::U8 )CreateTorusIndices(pc,tci->numberSlices,tci->numberStacks);else + return(nullptr); + } + + Primitive *p=pc->Create(); + + { + AABB aabb; + + // Calculate bounding box for the torus + float maxExtent = centerRadius + torusRadius; + float minExtent = centerRadius - torusRadius; + + aabb.SetMinMax(Vector3f(-maxExtent, -maxExtent, -torusRadius), + Vector3f( maxExtent, maxExtent, torusRadius)); //也许不对,待测试 + + p->SetBoundingBox(aabb); + } + + return p; + } + + namespace + { + template + void CreateCylinderIndices(PrimitiveCreater *pc,const uint numberSlices) + { + IBTypeMap ib_map(pc->GetIBMap()); + T *tp=ib_map; + uint i; + + T centerIndex = 0; + T indexCounter = 1; + + for (i = 0; i < numberSlices; i++) { - template - void CreateConeIndices(PrimitiveCreater *pc,const uint numberSlices,const uint numberStacks) - { - IBTypeMap ib_map(pc->GetIBMap()); - T *tp=ib_map; + *tp = centerIndex; ++tp; + *tp = indexCounter; ++tp; + *tp = indexCounter + 1; ++tp; - // Bottom - uint centerIndex = 0; - uint indexCounter = 1; - uint i,j; + indexCounter++; + } + indexCounter++; - for (i = 0; i < numberSlices; i++) - { - *tp = centerIndex; ++tp; - *tp = indexCounter; ++tp; - *tp = indexCounter + 1; ++tp; + // Top + centerIndex = indexCounter; + indexCounter++; - indexCounter++; - } - indexCounter++; - - // Sides - for (j = 0; j < numberStacks; j++) - { - for (i = 0; i < numberSlices; i++) - { - *tp = indexCounter; ++tp; - *tp = indexCounter + numberSlices + 1; ++tp; - *tp = indexCounter + 1; ++tp; - - *tp = indexCounter + 1; ++tp; - *tp = indexCounter + numberSlices + 1; ++tp; - *tp = indexCounter + numberSlices + 2; ++tp; - - indexCounter++; - } - indexCounter++; - } - } - }//namespace - - Primitive *CreateCone(PrimitiveCreater *pc,const ConeCreateInfo *cci) + for (i = 0; i < numberSlices; i++) { - uint i, j; + *tp = centerIndex; ++tp; + *tp = indexCounter + 1; ++tp; + *tp = indexCounter; ++tp; - uint numberVertices = (cci->numberSlices + 2) + (cci->numberSlices + 1) * (cci->numberStacks + 1); - uint numberIndices = cci->numberSlices * 3 + cci->numberSlices * 6 * cci->numberStacks; + indexCounter++; + } + indexCounter++; - if(!pc->Init("Cone",numberVertices,numberIndices)) - return(nullptr); + // Sides + for (i = 0; i < numberSlices; i++) + { + *tp = indexCounter; ++tp; + *tp = indexCounter + 1; ++tp; + *tp = indexCounter + 2; ++tp; - float angleStep = (2.0f * HGL_PI) / ((float) cci->numberSlices); + *tp = indexCounter + 2; ++tp; + *tp = indexCounter + 1; ++tp; + *tp = indexCounter + 3; ++tp; - float h = 2.0f * cci->halfExtend; - float r = cci->radius; - float l = sqrtf(h*h + r*r); + indexCounter += 2; + } + } + }//namespace - if (cci->numberSlices < 3 || cci->numberStacks < 1 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) - return nullptr; + Primitive *CreateCylinder(PrimitiveCreater *pc,const CylinderCreateInfo *cci) + { + uint numberIndices = cci->numberSlices * 3 * 2 + cci->numberSlices * 6; + + if(numberIndices<=0) + return(nullptr); + + uint numberVertices = (cci->numberSlices + 2) * 2 + (cci->numberSlices + 1) * 2; + + if(!pc->Init("Cylinder",numberVertices,numberIndices)) + return(nullptr); + + float angleStep = (2.0f * HGL_PI) / ((float) cci->numberSlices); + + if (cci->numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) + return nullptr; - VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); - VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); - VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); - VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); + VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); + VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); + VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); + VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); - float *vp=vertex; - float *np=normal; - float *tp=tangent; - float *tcp=tex_coord; + float *vp=vertex; + float *np=normal; + float *tp=tangent; + float *tcp=tex_coord; - if(!vp) - return(nullptr); + if(!vp) + return(nullptr); - *vp = 0.0f; ++vp; - *vp = 0.0f; ++vp; - *vp = -cci->halfExtend; ++vp; + *vp = 0.0f; ++vp; + *vp = 0.0f; ++vp; + *vp = -cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f; ++np; + *np = 0.0f; ++np; + *np =-1.0f; ++np; + } + + if(tp) + { + *tp = 0.0f; ++tp; + *tp = 1.0f; ++tp; + *tp = 0.0f; ++tp; + } + + if(tcp) + { + *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; + } + + for(uint i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; + + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = -cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f; ++np; + *np = 0.0f; ++np; + *np =-1.0f; ++np; + } + + if(tp) + { + *tp = sin(currentAngle); ++tp; + *tp = cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; + } + + if(tcp) + { + *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; + } + } + + *vp = 0.0f; ++vp; + *vp = 0.0f; ++vp; + *vp = cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f; ++np; + *np = 0.0f; ++np; + *np = 1.0f; ++np; + } + + if(tp) + { + *tp = 0.0f; ++tp; + *tp = -1.0f; ++tp; + *tp = 0.0f; ++tp; + } + + if(tcp) + { + *tcp = 1.0f; ++tcp; + *tcp = 1.0f; ++tcp; + } + + for(uint i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; + + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f; ++np; + *np = 0.0f; ++np; + *np = 1.0f; ++np; + } + + if(tp) + { + *tp = -sin(currentAngle); ++tp; + *tp = -cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; + } + + if(tcp) + { + *tcp = 1.0f; ++tcp; + *tcp = 1.0f; ++tcp; + } + } + + for(uint i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; + + float sign = -1.0f; + + for (uint j = 0; j < 2; j++) + { + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = cci->halfExtend * sign; ++vp; if(np) { - *np = 0.0f;++np; - *np = 0.0f;++np; - *np =-1.0f;++np; + *np = cos(currentAngle); ++np; + *np = -sin(currentAngle); ++np; + *np = 0.0f; ++np; } if(tp) { - *tp = 0.0f; ++tp; - *tp = 1.0f; ++tp; - *tp = 0.0f; ++tp; + *tp = -sin(currentAngle); ++tp; + *tp = -cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; } if(tcp) { - *tcp = 0.0f; ++tcp; - *tcp = 0.0f; ++tcp; + *tcp = (float)i / (float)cci->numberSlices; ++tcp; + *tcp = (sign + 1.0f) / 2.0f; ++tcp; } - for (i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; - - *vp = cos(currentAngle) * cci->radius; ++vp; - *vp = -sin(currentAngle) * cci->radius; ++vp; - *vp = -cci->halfExtend; ++vp; - - if(np) - { - *np = 0.0f;++np; - *np = 0.0f;++np; - *np =-1.0f;++np; - } - - if(tp) - { - *tp = sin(currentAngle); ++tp; - *tp = cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; - } - - if(tcp) - { - *tcp = 0.0f; ++tcp; - *tcp = 0.0f; ++tcp; - } - } - - for (j = 0; j < cci->numberStacks + 1; j++) - { - float level = (float)j / (float)cci->numberStacks; - - for (i = 0; i < cci->numberSlices + 1; i++) - { - float currentAngle = angleStep * (float)i; - - *vp = cos(currentAngle) * cci->radius * (1.0f - level); ++vp; - *vp = -sin(currentAngle) * cci->radius * (1.0f - level); ++vp; - *vp = -cci->halfExtend + 2.0f * cci->halfExtend * level; ++vp; - - if(np) - { - *np = h / l * cos(currentAngle); ++np; - *np =-h / l * sin(currentAngle); ++np; - *np = r / l; ++np; - } - - if(tp) - { - *tp = -sin(currentAngle); ++tp; - *tp = -cos(currentAngle); ++tp; - *tp = 0.0f; ++tp; - } - - if(tcp) - { - *tcp = (float)i / (float)cci->numberSlices; ++tcp; - *tcp = level; ++tcp; - } - } - } - - //索引 - { - const IndexType index_type=pc->GetIndexType(); - - if(index_type==IndexType::U16)CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else - if(index_type==IndexType::U32)CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else - if(index_type==IndexType::U8 )CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else - return(nullptr); - } - - return pc->Create(); + sign = 1.0f; } + } - Primitive *CreateAxis(PrimitiveCreater *pc,const AxisCreateInfo *aci) + //索引 + { + const IndexType index_type=pc->GetIndexType(); + + if(index_type==IndexType::U16)CreateCylinderIndices(pc,cci->numberSlices);else + if(index_type==IndexType::U32)CreateCylinderIndices(pc,cci->numberSlices);else + if(index_type==IndexType::U8 )CreateCylinderIndices(pc,cci->numberSlices);else + return(nullptr); + } + + Primitive *p=pc->Create(); + + p->SetBoundingBox( Vector3f(-cci->radius,-cci->radius,-cci->halfExtend), + Vector3f( cci->radius, cci->radius, cci->halfExtend)); + + return p; + } + + namespace + { + template + void CreateConeIndices(PrimitiveCreater *pc,const uint numberSlices,const uint numberStacks) + { + IBTypeMap ib_map(pc->GetIBMap()); + T *tp=ib_map; + + // Bottom + uint centerIndex = 0; + uint indexCounter = 1; + uint i,j; + + for (i = 0; i < numberSlices; i++) { - if(!pc||!aci)return(nullptr); + *tp = centerIndex; ++tp; + *tp = indexCounter; ++tp; + *tp = indexCounter + 1; ++tp; - if(!pc)return(nullptr); + indexCounter++; + } + indexCounter++; - if(!pc->Init("Axis",6,0)) - return(nullptr); + // Sides + for (j = 0; j < numberStacks; j++) + { + for (i = 0; i < numberSlices; i++) + { + *tp = indexCounter; ++tp; + *tp = indexCounter + numberSlices + 1; ++tp; + *tp = indexCounter + 1; ++tp; - VABMap3f vertex(pc->GetVABMap(VAN::Position)); - VABMap4f color(pc->GetVABMap(VAN::Color)); + *tp = indexCounter + 1; ++tp; + *tp = indexCounter + numberSlices + 1; ++tp; + *tp = indexCounter + numberSlices + 2; ++tp; - if(!vertex.IsValid()||!color.IsValid()) - return(nullptr); + indexCounter++; + } + indexCounter++; + } + } + }//namespace - const float s=aci->size; + Primitive *CreateCone(PrimitiveCreater *pc,const ConeCreateInfo *cci) + { + uint i, j; - vertex->Write(0,0,0);color->Write(aci->color[0]); - vertex->Write(s,0,0);color->Write(aci->color[0]); - vertex->Write(0,0,0);color->Write(aci->color[1]); - vertex->Write(0,s,0);color->Write(aci->color[1]); - vertex->Write(0,0,0);color->Write(aci->color[2]); - vertex->Write(0,0,s);color->Write(aci->color[2]); + uint numberVertices = (cci->numberSlices + 2) + (cci->numberSlices + 1) * (cci->numberStacks + 1); + uint numberIndices = cci->numberSlices * 3 + cci->numberSlices * 6 * cci->numberStacks; - return pc->Create(); + if(!pc->Init("Cone",numberVertices,numberIndices)) + return(nullptr); + + float angleStep = (2.0f * HGL_PI) / ((float) cci->numberSlices); + + float h = 2.0f * cci->halfExtend; + float r = cci->radius; + float l = sqrtf(h*h + r*r); + + if (cci->numberSlices < 3 || cci->numberStacks < 1 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES) + return nullptr; + + VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F); + VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F); + VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F); + VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F); + + float *vp=vertex; + float *np=normal; + float *tp=tangent; + float *tcp=tex_coord; + + if(!vp) + return(nullptr); + + *vp = 0.0f; ++vp; + *vp = 0.0f; ++vp; + *vp = -cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f;++np; + *np = 0.0f;++np; + *np =-1.0f;++np; + } + + if(tp) + { + *tp = 0.0f; ++tp; + *tp = 1.0f; ++tp; + *tp = 0.0f; ++tp; + } + + if(tcp) + { + *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; + } + + for (i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; + + *vp = cos(currentAngle) * cci->radius; ++vp; + *vp = -sin(currentAngle) * cci->radius; ++vp; + *vp = -cci->halfExtend; ++vp; + + if(np) + { + *np = 0.0f;++np; + *np = 0.0f;++np; + *np =-1.0f;++np; } - Primitive *CreateBoundingBox(PrimitiveCreater *pc,const BoundingBoxCreateInfo *cci) + if(tp) { - // Points of a cube. - /* 4 5 */ const float points[]={ -0.5,-0.5, 0.5, 0.5,-0.5,0.5, 0.5,-0.5,-0.5, -0.5,-0.5,-0.5, - /* *------------* */ -0.5, 0.5, 0.5, 0.5, 0.5,0.5, 0.5, 0.5,-0.5, -0.5, 0.5,-0.5}; - /* /| /| */ - /* 0/ | 1/ | */ - /* *--+---------* | */ - /* | | | | */ - /* | 7| | 6| */ - /* | *---------+--* */ - /* | / | / */ - /* |/ 2|/ */ - /* 3*------------* */ + *tp = sin(currentAngle); ++tp; + *tp = cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; + } - const uint16 indices[]= + if(tcp) + { + *tcp = 0.0f; ++tcp; + *tcp = 0.0f; ++tcp; + } + } + + for (j = 0; j < cci->numberStacks + 1; j++) + { + float level = (float)j / (float)cci->numberStacks; + + for (i = 0; i < cci->numberSlices + 1; i++) + { + float currentAngle = angleStep * (float)i; + + *vp = cos(currentAngle) * cci->radius * (1.0f - level); ++vp; + *vp = -sin(currentAngle) * cci->radius * (1.0f - level); ++vp; + *vp = -cci->halfExtend + 2.0f * cci->halfExtend * level; ++vp; + + if(np) { - 0,1, 1,2, 2,3, 3,0, - 4,5, 5,6, 6,7, 7,4, - 0,4, 1,5, 2,6, 3,7 - }; - - if(!pc)return(nullptr); - - if(!pc->Init("BoundingBox",8,24,IndexType::U16)) - return(nullptr); - - if(!pc->WriteVAB(VAN::Position,VF_V3F,points)) - return(nullptr); - - if(cci->color_type!=BoundingBoxCreateInfo::ColorType::NoColor) - { - RANGE_CHECK_RETURN_NULLPTR(cci->color_type); - - VABMap4f color(pc->GetVABMap(VAN::Color)); - - if(color.IsValid()) - { - if(cci->color_type==BoundingBoxCreateInfo::ColorType::SameColor) - color->RepeatWrite(cci->color[0],8); - else - if(cci->color_type==BoundingBoxCreateInfo::ColorType::VertexColor) - color->Write(cci->color,8); - } + *np = h / l * cos(currentAngle); ++np; + *np =-h / l * sin(currentAngle); ++np; + *np = r / l; ++np; } - pc->WriteIBO(indices); + if(tp) + { + *tp = -sin(currentAngle); ++tp; + *tp = -cos(currentAngle); ++tp; + *tp = 0.0f; ++tp; + } - return pc->Create(); + if(tcp) + { + *tcp = (float)i / (float)cci->numberSlices; ++tcp; + *tcp = level; ++tcp; + } } - }//namespace inline_geometry - }//namespace graph -}//namespace hgl + } + + //索引 + { + const IndexType index_type=pc->GetIndexType(); + + if(index_type==IndexType::U16)CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else + if(index_type==IndexType::U32)CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else + if(index_type==IndexType::U8 )CreateConeIndices(pc,cci->numberSlices,cci->numberStacks);else + return(nullptr); + } + + Primitive *p=pc->Create(); + + p->SetBoundingBox(Vector3f(-cci->radius,-cci->radius,-cci->halfExtend), + Vector3f( cci->radius, cci->radius, cci->halfExtend)); + + return p; + } + + Primitive *CreateAxis(PrimitiveCreater *pc,const AxisCreateInfo *aci) + { + if(!pc||!aci)return(nullptr); + + if(!pc)return(nullptr); + + if(!pc->Init("Axis",6,0)) + return(nullptr); + + VABMap3f vertex(pc->GetVABMap(VAN::Position)); + VABMap4f color(pc->GetVABMap(VAN::Color)); + + if(!vertex.IsValid()||!color.IsValid()) + return(nullptr); + + const float s=aci->size; + + vertex->Write(0,0,0);color->Write(aci->color[0]); + vertex->Write(s,0,0);color->Write(aci->color[0]); + vertex->Write(0,0,0);color->Write(aci->color[1]); + vertex->Write(0,s,0);color->Write(aci->color[1]); + vertex->Write(0,0,0);color->Write(aci->color[2]); + vertex->Write(0,0,s);color->Write(aci->color[2]); + + Primitive *p=pc->Create(); + + p->SetBoundingBox(Vector3f(0,0,0),Vector3f(s,s,s)); + + return p; + } + + Primitive *CreateBoundingBox(PrimitiveCreater *pc,const BoundingBoxCreateInfo *cci) + { + // Points of a cube. + /* 4 5 */ const float points[]={ -0.5,-0.5, 0.5, 0.5,-0.5,0.5, 0.5,-0.5,-0.5, -0.5,-0.5,-0.5, + /* *------------* */ -0.5, 0.5, 0.5, 0.5, 0.5,0.5, 0.5, 0.5,-0.5, -0.5, 0.5,-0.5}; + /* /| /| */ + /* 0/ | 1/ | */ + /* *--+---------* | */ + /* | | | | */ + /* | 7| | 6| */ + /* | *---------+--* */ + /* | / | / */ + /* |/ 2|/ */ + /* 3*------------* */ + + const uint16 indices[]= + { + 0,1, 1,2, 2,3, 3,0, + 4,5, 5,6, 6,7, 7,4, + 0,4, 1,5, 2,6, 3,7 + }; + + if(!pc)return(nullptr); + + if(!pc->Init("BoundingBox",8,24,IndexType::U16)) + return(nullptr); + + if(!pc->WriteVAB(VAN::Position,VF_V3F,points)) + return(nullptr); + + if(cci->color_type!=BoundingBoxCreateInfo::ColorType::NoColor) + { + RANGE_CHECK_RETURN_NULLPTR(cci->color_type); + + VABMap4f color(pc->GetVABMap(VAN::Color)); + + if(color.IsValid()) + { + if(cci->color_type==BoundingBoxCreateInfo::ColorType::SameColor) + color->RepeatWrite(cci->color[0],8); + else + if(cci->color_type==BoundingBoxCreateInfo::ColorType::VertexColor) + color->Write(cci->color,8); + } + } + + pc->WriteIBO(indices); + + Primitive *p=pc->Create(); + + p->SetBoundingBox( Vector3f(-0.5,-0.5,-0.5), + Vector3f( 0.5, 0.5, 0.5)); + + return p; + } +}//namespace hgl::graph::inline_geometry