Skip to content

Commit

Permalink
Primitives: tangents in the 3D grid primitive.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Mar 22, 2020
1 parent 1b776e1 commit b168616
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 183 deletions.
5 changes: 3 additions & 2 deletions doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ See also:
@subsubsection changelog-latest-new-primitives Primitives library

- @ref Primitives::capsule3DSolid(), @ref Primitives::circle3DSolid(),
@ref Primitives::coneSolid(), @ref Primitives::cylinderSolid() and
@ref Primitives::uvSphereSolid() can now have tangents as well
@ref Primitives::coneSolid(), @ref Primitives::cylinderSolid(),
@ref Primitives::grid3DSolid() and @ref Primitives::uvSphereSolid() can now
have tangents as well

@subsubsection changelog-latest-new-scenegraph SceneGraph library

Expand Down
24 changes: 17 additions & 7 deletions src/Magnum/Primitives/Grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,20 @@ Trade::MeshData grid3DSolid(const Vector2i& subdivisions, const GridFlags flags)
}
}

/* Allocate interleaved array for all vertex data */
/* Calculate attribute count and vertex size */
std::size_t stride = sizeof(Vector3);
std::size_t attributeCount = 1;
if(flags & GridFlag::Normals) {
++attributeCount;
stride += sizeof(Vector3);
++attributeCount;
}
if(flags & GridFlag::TextureCoordinates) {
if(flags & GridFlag::Tangents) {
stride += sizeof(Vector4);
++attributeCount;
}
if(flags & GridFlag::TextureCoordinates) {
stride += sizeof(Vector2);
++attributeCount;
}
Containers::Array<char> vertexData{stride*vertexCount.product()};
Containers::Array<Trade::MeshAttributeData> attributes{attributeCount};
Expand All @@ -86,8 +90,7 @@ Trade::MeshData grid3DSolid(const Vector2i& subdivisions, const GridFlags flags)
positions[i++] = {(Vector2(x, y)/Vector2(faceCount))*2.0f - Vector2{1.0f}, 0.0f};
}

/* Fill normals, if any. It's always the second attribute, right after
positions. */
/* Fill normals and tangents, if any. Those are the same for all. */
if(flags & GridFlag::Normals) {
Containers::StridedArrayView1D<Vector3> normals{vertexData,
reinterpret_cast<Vector3*>(vertexData.begin() + attributeOffset),
Expand All @@ -97,6 +100,15 @@ Trade::MeshData grid3DSolid(const Vector2i& subdivisions, const GridFlags flags)
attributeOffset += sizeof(Vector3);
for(auto&& i: normals) i = Vector3::zAxis(1.0f);
}
if(flags & GridFlag::Tangents) {
Containers::StridedArrayView1D<Vector4> tangents{vertexData,
reinterpret_cast<Vector4*>(vertexData.begin() + attributeOffset),
std::size_t(vertexCount.product()), std::ptrdiff_t(stride)};
attributes[attributeIndex++] =
Trade::MeshAttributeData{Trade::MeshAttribute::Tangent, tangents};
attributeOffset += sizeof(Vector4);
for(auto&& i: tangents) i = {1.0f, 0.0f, 0.0f, 1.0f};
}

if(flags & GridFlag::TextureCoordinates) {
Containers::StridedArrayView1D<Vector2> textureCoords{vertexData,
Expand All @@ -109,8 +121,6 @@ Trade::MeshData grid3DSolid(const Vector2i& subdivisions, const GridFlags flags)
textureCoords[i] = positions[i].xy()*0.5f + Vector2{0.5f};
}

/* Not using a compile-time attribute array because there's way too many
combinations */
return Trade::MeshData{MeshPrimitive::Triangles,
std::move(indexData), Trade::MeshIndexData{indices},
std::move(vertexData), std::move(attributes)};
Expand Down
14 changes: 11 additions & 3 deletions src/Magnum/Primitives/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,16 @@ enum class GridFlag: UnsignedByte {
* Generate normals in positive Z direction.
* @m_deprecated_since_latest Use @ref GridFlag::Normals instead.
*/
GenerateNormals CORRADE_DEPRECATED_ENUM("use Normals instead") = Normals
GenerateNormals CORRADE_DEPRECATED_ENUM("use Normals instead") = Normals,
#endif

/**
* Generate four-component tangents. The last component can be used to
* reconstruct a bitangent as described in the documentation of
* @ref Trade::MeshAttribute::Tangent.
* @m_since_latest
*/
Tangents = 1 << 2
};

/**
Expand All @@ -89,8 +97,8 @@ CORRADE_ENUMSET_OPERATORS(GridFlags)
2x2 grid in the XY plane with normals in positive Z direction.
@ref MeshPrimitive::Triangles with @ref MeshIndexType::UnsignedInt indices,
interleaved @ref VertexFormat::Vector3 positions, optional
@ref VertexFormat::Vector3 normals and @ref VertexFormat::Vector2 texture
coordinates.
@ref VertexFormat::Vector3 normals, optional @ref VertexFormat::Vector4
tangents and optional @ref VertexFormat::Vector2 texture coordinates.
@image html primitives-grid3dsolid.png width=256px
Expand Down
Loading

0 comments on commit b168616

Please sign in to comment.