@ -32,26 +32,39 @@
namespace Magnum { namespace Primitives {
namespace Magnum { namespace Primitives {
namespace {
constexpr Trade : : MeshAttributeData AttributeData2D [ ] {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , VertexFormat : : Vector2 ,
0 , 0 , sizeof ( Vector2 ) }
} ;
constexpr Trade : : MeshAttributeData AttributeData2DTextureCoords [ ] {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , VertexFormat : : Vector2 ,
0 , 0 , 2 * sizeof ( Vector2 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , VertexFormat : : Vector2 ,
sizeof ( Vector2 ) , 0 , 2 * sizeof ( Vector2 ) }
} ;
}
Trade : : MeshData circle2DSolid ( const UnsignedInt segments , const CircleTextureCoords textureCoords ) {
Trade : : MeshData circle2DSolid ( const UnsignedInt segments , const CircleTextureCoords textureCoords ) {
CORRADE_ASSERT ( segments > = 3 , " Primitives::circle2DSolid(): segments must be >= 3 " ,
CORRADE_ASSERT ( segments > = 3 , " Primitives::circle2DSolid(): segments must be >= 3 " ,
( Trade : : MeshData { MeshPrimitive : : TriangleFan , 0 } ) ) ;
( Trade : : MeshData { MeshPrimitive : : TriangleFan , 0 } ) ) ;
/* Allocate interleaved array for all vertex data */
/* Allocate interleaved array for all vertex data */
std : : size_t stride = sizeof ( Vector2 ) ;
Container s: : Array < Trade : : MeshAttributeData > attributes ;
std : : size_t attributeCount = 1 ;
if ( textureCoords = = CircleTextureCoords : : Generate )
if ( textureCoords = = CircleTextureCoords : : Generate ) {
attributes = Trade : : meshAttributeDataNonOwningArray ( AttributeData2DTextureCoords ) ;
+ + attributeCount ;
else
stride + = sizeof ( Vector2 ) ;
attributes = Trade : : meshAttributeDataNonOwningArray ( AttributeData2D ) ;
}
const std : : size_t stride = attributes [ 0 ] . stride ( ) ;
Containers : : Array < char > vertexData { stride * ( segments + 2 ) } ;
Containers : : Array < char > vertexData { stride * ( segments + 2 ) } ;
Containers : : Array < Trade : : MeshAttributeData > attributes { attributeCount } ;
/* Fill positions */
/* Fill positions */
Containers : : StridedArrayView1D < Vector2 > positions { vertexData ,
Containers : : StridedArrayView1D < Vector2 > positions { vertexData ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) ) ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) ) ,
segments + 2 , std : : ptrdiff_t ( stride ) } ;
segments + 2 , std : : ptrdiff_t ( stride ) } ;
attributes [ 0 ] =
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , positions } ;
positions [ 0 ] = { } ;
positions [ 0 ] = { } ;
/* Points on the circle. The first/last point is here twice to close the
/* Points on the circle. The first/last point is here twice to close the
circle properly . */
circle properly . */
@ -67,13 +80,11 @@ Trade::MeshData circle2DSolid(const UnsignedInt segments, const CircleTextureCoo
Containers : : StridedArrayView1D < Vector2 > textureCoords { vertexData ,
Containers : : StridedArrayView1D < Vector2 > textureCoords { vertexData ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) + sizeof ( Vector2 ) ) ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) + sizeof ( Vector2 ) ) ,
positions . size ( ) , std : : ptrdiff_t ( stride ) } ;
positions . size ( ) , std : : ptrdiff_t ( stride ) } ;
attributes [ 1 ] =
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , textureCoords } ;
for ( std : : size_t i = 0 ; i ! = positions . size ( ) ; + + i )
for ( std : : size_t i = 0 ; i ! = positions . size ( ) ; + + i )
textureCoords [ i ] = positions [ i ] * 0.5f + Vector2 { 0.5f } ;
textureCoords [ i ] = positions [ i ] * 0.5f + Vector2 { 0.5f } ;
}
}
return Trade : : MeshData { MeshPrimitive : : TriangleFan , std : : move ( vertexData ) , std : : move ( attributes ) } ;
return Trade : : MeshData { MeshPrimitive : : TriangleFan , std : : move ( vertexData ) , std : : move ( attributes ) , UnsignedInt ( positions . size ( ) ) } ;
}
}
Trade : : MeshData circle2DWireframe ( const UnsignedInt segments ) {
Trade : : MeshData circle2DWireframe ( const UnsignedInt segments ) {
@ -91,7 +102,33 @@ Trade::MeshData circle2DWireframe(const UnsignedInt segments) {
positions [ i ] = { sincos . second , sincos . first } ;
positions [ i ] = { sincos . second , sincos . first } ;
}
}
return Trade : : MeshData { MeshPrimitive : : LineLoop , std : : move ( vertexData ) , { Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , positions } } } ;
return Trade : : MeshData { MeshPrimitive : : LineLoop , std : : move ( vertexData ) ,
Trade : : meshAttributeDataNonOwningArray ( AttributeData2D ) , UnsignedInt ( positions . size ( ) ) } ;
}
namespace {
constexpr Trade : : MeshAttributeData AttributeData3D [ ] {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , VertexFormat : : Vector3 ,
0 , 0 , 2 * sizeof ( Vector3 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Normal , VertexFormat : : Vector3 ,
sizeof ( Vector3 ) , 0 , 2 * sizeof ( Vector3 ) }
} ;
constexpr Trade : : MeshAttributeData AttributeData3DTextureCoords [ ] {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , VertexFormat : : Vector3 ,
0 , 0 , 2 * sizeof ( Vector3 ) + sizeof ( Vector2 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Normal , VertexFormat : : Vector3 ,
sizeof ( Vector3 ) , 0 , 2 * sizeof ( Vector3 ) + sizeof ( Vector2 ) } ,
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , VertexFormat : : Vector2 ,
2 * sizeof ( Vector3 ) , 0 , 2 * sizeof ( Vector3 ) + sizeof ( Vector2 ) }
} ;
constexpr Trade : : MeshAttributeData AttributeData3DWireframe [ ] {
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , VertexFormat : : Vector3 ,
0 , 0 , sizeof ( Vector3 ) }
} ;
}
}
Trade : : MeshData circle3DSolid ( const UnsignedInt segments , CircleTextureCoords textureCoords ) {
Trade : : MeshData circle3DSolid ( const UnsignedInt segments , CircleTextureCoords textureCoords ) {
@ -99,21 +136,18 @@ Trade::MeshData circle3DSolid(const UnsignedInt segments, CircleTextureCoords te
( Trade : : MeshData { MeshPrimitive : : TriangleFan , 0 } ) ) ;
( Trade : : MeshData { MeshPrimitive : : TriangleFan , 0 } ) ) ;
/* Allocate interleaved array for all vertex data */
/* Allocate interleaved array for all vertex data */
std : : size_t stride = 2 * sizeof ( Vector3 ) ;
Container s: : Array < Trade : : MeshAttributeData > attributes ;
std : : size_t attributeCount = 2 ;
if ( textureCoords = = CircleTextureCoords : : Generate )
if ( textureCoords = = CircleTextureCoords : : Generate ) {
attributes = Trade : : meshAttributeDataNonOwningArray ( AttributeData3DTextureCoords ) ;
+ + attributeCount ;
else
stride + = sizeof ( Vector2 ) ;
attributes = Trade : : meshAttributeDataNonOwningArray ( AttributeData3D ) ;
}
const std : : size_t stride = attributes [ 0 ] . stride ( ) ;
Containers : : Array < char > vertexData { stride * ( segments + 2 ) } ;
Containers : : Array < char > vertexData { stride * ( segments + 2 ) } ;
Containers : : Array < Trade : : MeshAttributeData > attributes { attributeCount } ;
/* Fill positions */
/* Fill positions */
Containers : : StridedArrayView1D < Vector3 > positions { vertexData ,
Containers : : StridedArrayView1D < Vector3 > positions { vertexData ,
reinterpret_cast < Vector3 * > ( vertexData . begin ( ) ) ,
reinterpret_cast < Vector3 * > ( vertexData . begin ( ) ) ,
segments + 2 , std : : ptrdiff_t ( stride ) } ;
segments + 2 , std : : ptrdiff_t ( stride ) } ;
attributes [ 0 ] =
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , positions } ;
positions [ 0 ] = { } ;
positions [ 0 ] = { } ;
/* Points on the circle. The first/last point is here twice to close the
/* Points on the circle. The first/last point is here twice to close the
circle properly . */
circle properly . */
@ -128,8 +162,6 @@ Trade::MeshData circle3DSolid(const UnsignedInt segments, CircleTextureCoords te
Containers : : StridedArrayView1D < Vector3 > normals { vertexData ,
Containers : : StridedArrayView1D < Vector3 > normals { vertexData ,
reinterpret_cast < Vector3 * > ( vertexData . begin ( ) + sizeof ( Vector3 ) ) ,
reinterpret_cast < Vector3 * > ( vertexData . begin ( ) + sizeof ( Vector3 ) ) ,
segments + 2 , std : : ptrdiff_t ( stride ) } ;
segments + 2 , std : : ptrdiff_t ( stride ) } ;
attributes [ 1 ] =
Trade : : MeshAttributeData { Trade : : MeshAttribute : : Normal , normals } ;
for ( Vector3 & normal : normals ) normal = Vector3 : : zAxis ( 1.0f ) ;
for ( Vector3 & normal : normals ) normal = Vector3 : : zAxis ( 1.0f ) ;
/* Fill texture coords, if any */
/* Fill texture coords, if any */
@ -137,13 +169,11 @@ Trade::MeshData circle3DSolid(const UnsignedInt segments, CircleTextureCoords te
Containers : : StridedArrayView1D < Vector2 > textureCoords { vertexData ,
Containers : : StridedArrayView1D < Vector2 > textureCoords { vertexData ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) + 2 * sizeof ( Vector3 ) ) ,
reinterpret_cast < Vector2 * > ( vertexData . begin ( ) + 2 * sizeof ( Vector3 ) ) ,
positions . size ( ) , std : : ptrdiff_t ( stride ) } ;
positions . size ( ) , std : : ptrdiff_t ( stride ) } ;
attributes [ 2 ] =
Trade : : MeshAttributeData { Trade : : MeshAttribute : : TextureCoordinates , textureCoords } ;
for ( std : : size_t i = 0 ; i ! = positions . size ( ) ; + + i )
for ( std : : size_t i = 0 ; i ! = positions . size ( ) ; + + i )
textureCoords [ i ] = positions [ i ] . xy ( ) * 0.5f + Vector2 { 0.5f } ;
textureCoords [ i ] = positions [ i ] . xy ( ) * 0.5f + Vector2 { 0.5f } ;
}
}
return Trade : : MeshData { MeshPrimitive : : TriangleFan , std : : move ( vertexData ) , std : : move ( attributes ) } ;
return Trade : : MeshData { MeshPrimitive : : TriangleFan , std : : move ( vertexData ) , std : : move ( attributes ) , UnsignedInt ( positions . size ( ) ) } ;
}
}
Trade : : MeshData circle3DWireframe ( const UnsignedInt segments ) {
Trade : : MeshData circle3DWireframe ( const UnsignedInt segments ) {
@ -161,7 +191,8 @@ Trade::MeshData circle3DWireframe(const UnsignedInt segments) {
positions [ i ] = { sincos . second , sincos . first , 0.0f } ;
positions [ i ] = { sincos . second , sincos . first , 0.0f } ;
}
}
return Trade : : MeshData { MeshPrimitive : : LineLoop , std : : move ( vertexData ) , { Trade : : MeshAttributeData { Trade : : MeshAttribute : : Position , positions } } } ;
return Trade : : MeshData { MeshPrimitive : : LineLoop , std : : move ( vertexData ) ,
Trade : : meshAttributeDataNonOwningArray ( AttributeData3DWireframe ) , UnsignedInt ( positions . size ( ) ) } ;
}
}
} }
} }