Skip to content

Instantly share code, notes, and snippets.

@johnmcfarlane
Created November 25, 2015 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnmcfarlane/5b2dd36dfeb565919489 to your computer and use it in GitHub Desktop.
Save johnmcfarlane/5b2dd36dfeb565919489 to your computer and use it in GitHub Desktop.
zoox::unique_ptr<FRawMesh> ReadPly(ByteBuffer const & buffer)
{
// read the header
constexpr auto header =
"ply\n\n"
"format binary_little_endian 1.0\n"
"comment This contains a Splatted Point Cloud\n"
"element vertex %d\n"
"property float x\n"
"property float y\n"
"property float z\n"
"property float nx\n"
"property float ny\n"
"property float nz\n"
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
"element face %d\n"
"property list uchar int vertex_indices\n"
"end_header\n%n";
int num_vertices, num_faces, header_bytes;
int scanned = zoox::sscanf(reinterpret_cast<char const *>(buffer.data()), header, &num_vertices, &num_faces, &header_bytes);
if (scanned != 2)
{
return nullptr;
}
// map out the lists of vertices and faces
#pragma pack(push, 1)
struct Vertex
{
zoox::array<float, 3> position;
zoox::array<float, 3> normal;
zoox::array<zoox::uint8_t, 4> color;
};
struct Face
{
zoox::uint8_t num_faces;
zoox::array<zoox::int32_t, 3> indices;
};
#pragma pack(pop)
auto vertices_begin = reinterpret_cast<Vertex const *>(buffer.data() + header_bytes);
auto vertices_end = vertices_begin + num_vertices;
auto faces_begin = reinterpret_cast<Face const *>(vertices_end);
auto faces_end = faces_begin + num_faces;
// ensure that the file matches the lists
if (reinterpret_cast<ByteBuffer::value_type const *>(faces_end) != buffer.data() + buffer.size())
{
return nullptr;
}
// allocate a return object
auto result = zoox::unique_ptr<FRawMesh>(new FRawMesh);
// read the vertex positions
result->VertexPositions.Reserve(num_vertices);
for (auto vertex_iterator = vertices_begin; vertex_iterator != vertices_end; ++vertex_iterator)
{
result->VertexPositions.Emplace(
vertex_iterator->position[0],
vertex_iterator->position[1],
vertex_iterator->position[2]);
}
auto num_wedges = num_faces * 3;
result->WedgeColors.Reserve(num_wedges);
result->WedgeIndices.Reserve(num_wedges);
result->WedgeTangentX.Reserve(num_wedges);
result->WedgeTangentY.Reserve(num_wedges);
result->WedgeTangentZ.Reserve(num_wedges);
//result->WedgeTexCoords.Reserve(num_wedges);
for (auto face_iterator = faces_begin; face_iterator != faces_end; ++face_iterator)
{
if (face_iterator->num_faces != 3)
{
return nullptr;
}
for (auto index : face_iterator->indices)
{
if (index < 0 || index >= num_vertices)
{
return nullptr;
}
auto const & vertex = vertices_begin[index];
result->WedgeColors.Emplace(
vertex.color[0],
vertex.color[1],
vertex.color[2],
vertex.color[3]);
result->WedgeIndices.Emplace(index);
result->WedgeTangentX.Emplace(FVector::ZeroVector);
result->WedgeTangentY.Emplace(FVector::ZeroVector);
result->WedgeTangentZ.Emplace(
vertex.normal[0],
vertex.normal[1],
vertex.normal[2]);
//result->WedgeTexCoords.Emplace(FVector2D::ZeroVector);
}
}
ensure(result->WedgeColors.Num() == num_wedges);
ensure(result->WedgeIndices.Num() == num_wedges);
ensure(result->WedgeTangentX.Num() == num_wedges);
ensure(result->WedgeTangentY.Num() == num_wedges);
ensure(result->WedgeTangentZ.Num() == num_wedges);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment