| 132 | |
| 133 | |
| 134 | void GltfWriter::write(const PointViewPtr v) |
| 135 | { |
| 136 | TriangularMesh *mesh = v->mesh(); |
| 137 | if (!mesh) |
| 138 | { |
| 139 | log()->get(LogLevel::Warning) << "Attempt to write point view with no mesh. Skipping.\n"; |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | OLeStream& out = *m_stream; |
| 144 | |
| 145 | ViewData vd; |
| 146 | vd.m_indexCount = mesh->size() * 3; |
| 147 | vd.m_vertexCount = v->size(); |
| 148 | vd.m_indexOffset = m_binSize; |
| 149 | vd.m_indexByteLength = vd.m_indexCount * sizeof(uint32_t); |
| 150 | vd.m_vertexOffset = vd.m_indexOffset + vd.m_indexByteLength; |
| 151 | vd.m_vertexByteLength = v->size() * sizeof(float) * 3; // 3 for X,Y,Z |
| 152 | |
| 153 | if (m_writeNormals) |
| 154 | // Add the length of 3 normals to the vertex byte length |
| 155 | vd.m_vertexByteLength += v->size() * sizeof(float) * 3; // 3 for X,Y,Z |
| 156 | |
| 157 | if (m_colorVertices) |
| 158 | // Add the length of 3 colors to the vertex byte length |
| 159 | vd.m_vertexByteLength += v->size() * sizeof(float) * 3; // 3 for R,G,B |
| 160 | |
| 161 | m_binSize += vd.m_indexByteLength + vd.m_vertexByteLength; |
| 162 | m_totalSize = static_cast<size_t>(out.position()) + m_binSize; |
| 163 | if (m_totalSize > (std::numeric_limits<uint32_t>::max)()) |
| 164 | throwError("Data too large for file."); |
| 165 | |
| 166 | for (const Triangle& t : *mesh) |
| 167 | out << (uint32_t)t.m_a << (uint32_t)t.m_b << (uint32_t)t.m_c; |
| 168 | |
| 169 | for (PointId i = 0; i < v->size(); ++i) |
| 170 | { |
| 171 | float x = v->getFieldAs<float>(Dimension::Id::X, i); |
| 172 | float y = v->getFieldAs<float>(Dimension::Id::Y, i); |
| 173 | float z = v->getFieldAs<float>(Dimension::Id::Z, i); |
| 174 | |
| 175 | vd.m_bounds.grow(x, y, z); |
| 176 | out << x << y << z; |
| 177 | |
| 178 | // This assumes that the normals are unit vectors. Doesn't seem worth verifying. |
| 179 | if (m_writeNormals) |
| 180 | { |
| 181 | out << v->getFieldAs<float>(Dimension::Id::NormalX, i) << |
| 182 | v->getFieldAs<float>(Dimension::Id::NormalY, i) << |
| 183 | v->getFieldAs<float>(Dimension::Id::NormalZ, i); |
| 184 | } |
| 185 | |
| 186 | // PDAL colors should be 16 bit unsigned and we need floating values [0, 1]. |
| 187 | if (m_colorVertices) |
| 188 | { |
| 189 | const double scale = (std::numeric_limits<uint16_t>::max)(); |
| 190 | double r = v->getFieldAs<double>(Dimension::Id::Red, i) / scale; |
| 191 | double g = v->getFieldAs<double>(Dimension::Id::Green, i) / scale; |