Skip to content

Commit

Permalink
Merge pull request #12 from connormanning/cesium
Browse files Browse the repository at this point in the history
Add initial 3D Tiles output prototype.
  • Loading branch information
connormanning committed Sep 20, 2016
2 parents c05d414 + 9af8dc7 commit f41ac27
Show file tree
Hide file tree
Showing 43 changed files with 2,250 additions and 74 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ add_subdirectory(entwine)
add_subdirectory(kernel)

set(OBJS
$<TARGET_OBJECTS:formats>
$<TARGET_OBJECTS:reader>
$<TARGET_OBJECTS:third>
$<TARGET_OBJECTS:tree>
Expand Down
1 change: 1 addition & 0 deletions config/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*
!cesium.json
!.gitignore

14 changes: 14 additions & 0 deletions config/cesium.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"geometry": {
"reproject": {
"out": "EPSG:4978"
}
},
"formats": {
"cesium": {
"tilesetSplit": 8,
"geometricErrorDivisor": 16.0
}
}
}

1 change: 1 addition & 0 deletions entwine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ add_subdirectory(reader)
add_subdirectory(third)
add_subdirectory(types)
add_subdirectory(util)
add_subdirectory(formats)

3 changes: 3 additions & 0 deletions entwine/formats/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set(MODULE formats)
add_subdirectory(cesium)

26 changes: 26 additions & 0 deletions entwine/formats/cesium/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
set(MODULE formats)
set(BASE "${CMAKE_CURRENT_SOURCE_DIR}")

set(
SOURCES
"${BASE}/feature-table.cpp"
"${BASE}/settings.cpp"
"${BASE}/tile.cpp"
"${BASE}/tile-builder.cpp"
"${BASE}/tile-info.cpp"
)

set(
HEADERS
"${BASE}/feature-table.hpp"
"${BASE}/settings.hpp"
"${BASE}/tile.hpp"
"${BASE}/tile-builder.hpp"
"${BASE}/tile-info.hpp"
"${BASE}/tileset.hpp"
"${BASE}/util.hpp"
)

install(FILES ${HEADERS} DESTINATION include/entwine/formats/cesium)
add_library(${MODULE} OBJECT ${SOURCES})

208 changes: 208 additions & 0 deletions entwine/formats/cesium/feature-table.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
/******************************************************************************
* Copyright (c) 2016, Connor Manning (connor@hobu.co)
*
* Entwine -- Point cloud indexing
*
* Entwine is available under the terms of the LGPL2 license. See COPYING
* for specific license text and more information.
*
******************************************************************************/

#include <entwine/formats/cesium/feature-table.hpp>

#include <iostream>
#include <stdexcept>

namespace entwine
{
namespace cesium
{

namespace
{
const double dmin(std::numeric_limits<double>::min());
const double dmax(std::numeric_limits<double>::max());
}

FeatureTable::FeatureTable(
const std::vector<Point>& points,
const std::vector<Color>& colors)
: m_points(points)
, m_colors(colors)
{
if (colors.size() && colors.size() != points.size())
{
std::cout << colors.size() << " != " << points.size() << std::endl;
throw std::runtime_error("Invalid colors size");
}
}

Json::Value FeatureTable::getJson() const
{
Json::Value json;
json["POINTS_LENGTH"] = Json::UInt64(m_points.size());
json["POSITION"]["byteOffset"] = 0;

if (m_colors.size())
{
json["RGB"]["byteOffset"] =
Json::UInt64(m_points.size() * 3 * sizeof(float));
}

/*
json["RTC_CENTER"].append(m_center.x);
json["RTC_CENTER"].append(m_center.y);
json["RTC_CENTER"].append(m_center.z);
*/

return json;
}

std::vector<char> FeatureTable::getBinary() const
{
std::vector<char> data;
data.reserve(
m_points.size() * 3 * sizeof(float) +
m_colors.size() * 3 * sizeof(uint8_t));

float f;
for (const Point& p : m_points)
{
f = p.x;
data.insert(
data.end(),
reinterpret_cast<const char*>(&f),
reinterpret_cast<const char*>(&f + 1));

f = p.y;
data.insert(
data.end(),
reinterpret_cast<const char*>(&f),
reinterpret_cast<const char*>(&f + 1));

f = p.z;
data.insert(
data.end(),
reinterpret_cast<const char*>(&f),
reinterpret_cast<const char*>(&f + 1));
}

for (const Color& c : m_colors)
{
data.push_back(c.r);
data.push_back(c.g);
data.push_back(c.b);
}

return data;
}

FeatureTable::FeatureTable(const Json::Value& json, const char* pos)
{
if (!json.isMember("POINTS_LENGTH"))
{
throw std::runtime_error("Required POINTS_LENGTH not found");
}

const std::size_t numPoints(json["POINTS_LENGTH"].asUInt64());

std::cout << "Number of points: " << numPoints << std::endl;

if (json.isMember("POSITION"))
{
std::cout << "Found floating point positions" << std::endl;
m_points.reserve(numPoints * 3);

Point center;

if (json.isMember("RTC_CENTER"))
{
const auto& centerJson(json["RTC_CENTER"]);
center = Point(
centerJson[0].asDouble(),
centerJson[1].asDouble(),
centerJson[2].asDouble());

std::cout << "Got RTC center: " << center << std::endl;
}

const std::size_t pointDataOffset(
json["POSITION"]["byteOffset"].asUInt64());

const char* pointPos(pos + pointDataOffset);
const char* pointEnd(pointPos + numPoints * 3 * sizeof(float));

for ( ; pointPos < pointEnd; pointPos += 3 * sizeof(float))
{
m_points.emplace_back(
*reinterpret_cast<const float*>(pointPos + 0),
*reinterpret_cast<const float*>(pointPos + 4),
*reinterpret_cast<const float*>(pointPos + 8));
}

summarizePoints();
}
else if (json.isMember("POSITION_QUANTIZED"))
{
std::cout << "Found quantized point positions" << std::endl;
}
else
{
throw std::runtime_error("No POSITION or POSITION_QUANTIZED found");
}

if (json.isMember("RGB"))
{
m_colors.reserve(numPoints * 3);

const std::size_t colorDataOffset(
json["RGB"]["byteOffset"].asUInt64());

const char* colorPos(pos + colorDataOffset);
const char* colorEnd(colorPos + numPoints * 3 * sizeof(uint8_t));

for ( ; colorPos < colorEnd; colorPos += 3 * sizeof(uint8_t))
{
m_colors.emplace_back(
*(colorPos + 0),
*(colorPos + 1),
*(colorPos + 2));
}

summarizeColors();
}
}

void FeatureTable::summarizePoints() const
{
Point min(dmax, dmax, dmax);
Point max(dmin, dmin, dmin);

for (const Point& p : m_points)
{
min = Point::min(min, p);
max = Point::max(max, p);
}

std::cout << "Point min: " << min << std::endl;
std::cout << "Point max: " << max << std::endl;
}

void FeatureTable::summarizeColors() const
{
Color min(255, 255, 255);
Color max(0, 0, 0);

for (const Color& c : m_colors)
{
min = Color::min(min, c);
max = Color::max(max, c);
}

std::cout << "Color min: " << min << std::endl;
std::cout << "Color max: " << max << std::endl;
}

} // namespace cesium
} // namespace entwine

50 changes: 50 additions & 0 deletions entwine/formats/cesium/feature-table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/******************************************************************************
* Copyright (c) 2016, Connor Manning (connor@hobu.co)
*
* Entwine -- Point cloud indexing
*
* Entwine is available under the terms of the LGPL2 license. See COPYING
* for specific license text and more information.
*
******************************************************************************/

#pragma once

#include <vector>

#include <json/json.h>

#include <entwine/types/point.hpp>

namespace entwine
{
namespace cesium
{

class FeatureTable
{
public:
FeatureTable() = default;

FeatureTable(
const std::vector<Point>& points,
const std::vector<Color>& colors);

// Not really used anywhere, but may be useful for output validation.
FeatureTable(const Json::Value& json, const char* pos);

Json::Value getJson() const;

std::vector<char> getBinary() const;

private:
void summarizePoints() const;
void summarizeColors() const;

std::vector<Point> m_points;
std::vector<Color> m_colors;
};

} // namespace cesium
} // namespace entwine

48 changes: 48 additions & 0 deletions entwine/formats/cesium/settings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/******************************************************************************
* Copyright (c) 2016, Connor Manning (connor@hobu.co)
*
* Entwine -- Point cloud indexing
*
* Entwine is available under the terms of the LGPL2 license. See COPYING
* for specific license text and more information.
*
******************************************************************************/

#include <entwine/formats/cesium/settings.hpp>

namespace entwine
{
namespace cesium
{

Settings::Settings(
std::size_t tilesetSplit,
double geometricErrorDivisor,
std::string coloring)
: m_tilesetSplit(tilesetSplit)
, m_geometricErrorDivisor(geometricErrorDivisor)
, m_coloring(coloring)
{
if (!m_tilesetSplit) m_tilesetSplit = 8;
if (m_geometricErrorDivisor == 0.0) m_geometricErrorDivisor = 8.0;
}

Settings::Settings(const Json::Value& json)
: Settings(
json["tilesetSplit"].asUInt64(),
json["geometricErrorDivisor"].asDouble(),
json["coloring"].asString())
{ }

Json::Value Settings::toJson() const
{
Json::Value json;
json["tilesetSplit"] = Json::UInt64(m_tilesetSplit);
json["geometricErrorDivisor"] = m_geometricErrorDivisor;
if (m_coloring.size()) json["coloring"] = m_coloring;
return json;
}

} // namespace cesium
} // namespace entwine

Loading

0 comments on commit f41ac27

Please sign in to comment.