Skip to content

Commit

Permalink
Merge pull request #1205 from tangrams/curved-lables-pt1
Browse files Browse the repository at this point in the history
Preparation for curved labels
  • Loading branch information
karimnaaji authored Jan 25, 2017
2 parents 61e4bf2 + 3877dd4 commit 78770dc
Show file tree
Hide file tree
Showing 23 changed files with 819 additions and 494 deletions.
131 changes: 16 additions & 115 deletions core/src/labels/label.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#include "label.h"

#include "util/geom.h"
#include "glm/gtx/rotate_vector.hpp"
#include "glm/gtx/norm.hpp"
#include "tangram.h"
#include "platform.h"
#include "view/view.h"
#include "log.h"
Expand All @@ -14,18 +11,20 @@ namespace Tangram {

const float Label::activation_distance_threshold = 2;

Label::Label(Label::WorldTransform _worldTransform, glm::vec2 _size,
Type _type, Options _options)
: m_state(State::none),
m_type(_type),
m_worldTransform(_worldTransform),
Label::Label(glm::vec2 _size, Type _type, Options _options)
: m_type(_type),
m_dim(_size),
m_options(_options) {
m_options(_options),
m_state(State::none) {

if (!m_options.collide || m_type == Type::debug) {
enterState(State::visible, 1.0);
if (m_type == Type::debug) {
m_options.collide = false;
}

if (m_options.collide) {
enterState(State::none, 0.0);
} else {
m_screenTransform.alpha = 0.0;
enterState(State::visible, 1.0);
}

m_occludedLastFrame = false;
Expand All @@ -50,74 +49,6 @@ void Label::setParent(Label& _parent, bool _definePriority, bool _defineCollide)
applyAnchor(m_options.anchors[m_anchorIndex]);
}

float Label::screenDistance2(glm::vec2 _screenPosition) const {
return glm::length2(m_obb.getCentroid() - _screenPosition);
}

LngLat Label::coordinates(const Tile& _tile, const MapProjection& _projection) {
LngLat coordinates;
int coordCount = m_type == Type::line ? 2 : 1;
for (int i = 0; i < coordCount; ++i) {
glm::vec2 tileCoord = glm::vec2(m_worldTransform.positions[i]);
glm::dvec2 degrees = _tile.coordToLngLat(tileCoord, _projection);
coordinates.longitude += degrees.x;
coordinates.latitude += degrees.y;
}
coordinates.longitude /= coordCount;
coordinates.latitude /= coordCount;

return coordinates;
}

float Label::worldLineLength2() const {
float worldLength2 = 0.f;

if (m_type == Type::line) {
worldLength2 = glm::length2(m_worldTransform.positions[0] - m_worldTransform.positions[1]);
}

return worldLength2;
}

bool Label::offViewport(const glm::vec2& _screenSize) {
const auto& quad = m_obb.getQuad();

for (int i = 0; i < 4; ++i) {
if (m_options.flat) {
if (m_screenTransform.positions[i].x < _screenSize.x
&& m_screenTransform.positions[i].x > 0
&& m_screenTransform.positions[i].y < _screenSize.y
&& m_screenTransform.positions[i].y > 0) {
return false;
}
} else {
if (quad[i].x < _screenSize.x && quad[i].x > 0 &&
quad[i].y < _screenSize.y && quad[i].y > 0) {
return false;
}
}
}

return true;
}

bool Label::canOcclude() {
if (!m_options.collide) {
return false;
}

int occludeFlags = (State::visible |
State::none |
State::skip_transition |
State::fading_in |
State::fading_out |
State::sleep |
State::out_of_screen |
State::dead);

return (occludeFlags & m_state) && !(m_type == Type::debug);
}

bool Label::visibleState() const {
int visibleFlags = (State::visible |
State::fading_in |
Expand All @@ -131,10 +62,6 @@ void Label::skipTransitions() {
enterState(State::skip_transition, 0.0);
}

glm::vec2 Label::center() const {
return m_obb.getCentroid();
}

void Label::enterState(const State& _state, float _alpha) {
if (m_state == State::dead) { return; }

Expand All @@ -145,11 +72,10 @@ void Label::enterState(const State& _state, float _alpha) {
// Reset anchor fallback index
m_anchorIndex = 0;
}

}

void Label::setAlpha(float _alpha) {
m_screenTransform.alpha = CLAMP(_alpha, 0.0, 1.0);
m_alpha = CLAMP(_alpha, 0.0, 1.0);
}

void Label::resetState() {
Expand Down Expand Up @@ -179,8 +105,6 @@ void Label::print() const {
}
LOG("\tm_state: %s", state.c_str());
LOG("\tm_anchorIndex: %d", m_anchorIndex);
LOG("\tscreenPos: %f/%f", m_screenTransform.position.x, m_screenTransform.position.y);

}

bool Label::nextAnchor() {
Expand All @@ -201,41 +125,18 @@ bool Label::setAnchorIndex(int _index) {
return true;
}

bool Label::update(const glm::mat4& _mvp, const ViewState& _viewState, bool _drawAllLabels) {
bool Label::update(const glm::mat4& _mvp, const ViewState& _viewState,
const AABB* _bounds, ScreenTransform& _transform) {

m_occludedLastFrame = m_occluded;
m_occluded = false;

if (m_state == State::dead) {
if (_drawAllLabels) {
m_occluded = true;
} else {
return false;
}
}

bool ruleSatisfied = updateScreenTransform(_mvp, _viewState, _drawAllLabels);

// one of the label rules has not been satisfied
if (!ruleSatisfied) {
bool valid = updateScreenTransform(_mvp, _viewState, _bounds, _transform);
if (!valid) {
enterState(State::sleep, 0.0);
return false;
}

// update the view-space bouding box
updateBBoxes(_viewState.fractZoom);

// checks whether the label is out of the viewport
if (offViewport(_viewState.viewportSize)) {
enterState(State::out_of_screen, 0.0);
if (m_occludedLastFrame) {
m_occluded = true;
return false;
}
} else if (m_state == State::out_of_screen) {
enterState(State::sleep, 0.0);
}

return true;
}

Expand Down
115 changes: 34 additions & 81 deletions core/src/labels/label.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

namespace Tangram {

struct ScreenTransform;
struct ViewState;
class Tile;
class MapProjection;
struct OBBBuffer;

class Label {

Expand All @@ -46,31 +46,6 @@ class Label {
dead = 1 << 7,
};

struct WorldTransform {
WorldTransform(glm::vec3 _wp) : position(_wp) {}
WorldTransform(glm::vec2 _wp0, glm::vec2 _wp1) {
positions[0] = _wp0;
positions[1] = _wp1;
}

union {
glm::vec3 position; // The label position if the label is not a line
// position.z stores the zoom-level
glm::vec2 positions[2]; // The label positions if the label is a line
};
};

struct ScreenTransform {
ScreenTransform() {}
union {
glm::vec2 position; // The label position if the label is not flattened
glm::vec2 positions[4]; // The label positions if the label is flattened
};

glm::vec2 rotation = {1.f, 0.f};
float alpha = 0.f;
};

struct Transition {
FadeEffect::Interpolation ease = FadeEffect::Interpolation::linear;
float time = 0.0;
Expand All @@ -96,54 +71,48 @@ class Label {

static const float activation_distance_threshold;

Label(WorldTransform _transform, glm::vec2 _size, Type _type, Options _options);
Label(glm::vec2 _size, Type _type, Options _options);

virtual ~Label();

// Add vertices for this label to its Style's shared Mesh
virtual void addVerticesToMesh() = 0;
virtual glm::vec2 center() const;
virtual void updateBBoxes(float _zoomFract) = 0;
virtual void addVerticesToMesh(ScreenTransform& _transform, const glm::vec2& _screenSize) = 0;

virtual LabelType renderType() const = 0;

// Update the screen position of the label
virtual bool updateScreenTransform(const glm::mat4& _mvp, const ViewState& _viewState, bool _drawAllLabels) = 0;

virtual uint32_t selectionColor() = 0;

bool update(const glm::mat4& _mvp,
const ViewState& _viewState,
bool _drawAllLabels = false);
virtual glm::vec2 modelCenter() const = 0;

bool update(const glm::mat4& _mvp, const ViewState& _viewState,
const AABB* _bounds, ScreenTransform& _transform);

bool evalState(float _dt);

// Update the screen position of the label
virtual bool updateScreenTransform(const glm::mat4& _mvp, const ViewState& _viewState,
const AABB* _bounds, ScreenTransform& _transform) = 0;

// Current screen position of the label anchor
glm::vec2 screenCenter() const { return m_screenCenter; }

// Occlude the label
void occlude(bool _occlusion = true) { m_occluded = _occlusion; }

// Checks whether the label is in a state where it can occlusion
bool canOcclude();
bool canOcclude() const { return m_options.collide; }

void skipTransitions();

size_t hash() const { return m_options.paramHash; }

const glm::vec2& dimension() const { return m_dim; }
glm::vec2 dimension() const { return m_dim; }

// Gets for label options: color and offset
const Options& options() const { return m_options; }

// Gets the extent of the oriented bounding box of the label
AABB aabb() const { return m_obb.getExtent(); }

// Gets the oriented bounding box of the label
const OBB& obb() const { return m_obb; }

// The label world transform (position with the tile, in tile units)
const WorldTransform& worldTransform() const { return m_worldTransform; }

// The label screen transform, in a top left coordinate axis, y pointing down
const ScreenTransform& screenTransform() const { return m_screenTransform; }
// Adds the oriented bounding boxes of the label to _obbs, updates Range
virtual void obbs(ScreenTransform& _transform, OBBBuffer& _obbs) = 0;

State state() const { return m_state; }

Expand All @@ -154,22 +123,18 @@ class Label {
Label* parent() const { return m_parent; }
void setParent(Label& parent, bool definePriority, bool defineCollide);

LabelProperty::Anchor anchorType() const { return m_options.anchors[m_anchorIndex]; }
LabelProperty::Anchor anchorType() const {
return m_options.anchors[m_anchorIndex];
}

int anchorIndex() { return m_anchorIndex; }

bool nextAnchor();

bool setAnchorIndex(int _index);

// Returns the list of lon/lat of the feature the label is associated with
LngLat coordinates(const Tile& _tile, const MapProjection& _projection);

// Returns the screen distance squared from a screen coordinate
float screenDistance2(glm::vec2 _screenPosition) const;

// Returns the length of the segment the label is associated with
float worldLineLength2() const;
virtual float modelLineLength2() const { return 0; };

void enterState(const State& _state, float _alpha = 1.0f);

Expand All @@ -182,42 +147,30 @@ class Label {

void print() const;

bool offViewport(const glm::vec2& _screenSize);

void setAlpha(float _alpha);

private:
protected:

virtual void applyAnchor(LabelProperty::Anchor _anchor) = 0;

State m_state;
const Type m_type;
const glm::vec2 m_dim;

Options m_options;

Label* m_parent;

State m_state;
FadeEffect m_fade;

int m_anchorIndex;

protected:
glm::vec2 m_anchor;

bool m_occludedLastFrame;

bool m_occluded;

Type m_type;

OBB m_obb;

WorldTransform m_worldTransform;

ScreenTransform m_screenTransform;

glm::vec2 m_dim;

Options m_options;

glm::vec2 m_anchor;

Label* m_parent;

glm::vec2 m_screenCenter;
float m_alpha;
};

}
Expand Down
Loading

0 comments on commit 78770dc

Please sign in to comment.