Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Improve resize UI quality #968

Merged
merged 1 commit into from
Feb 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions app/src/main/cpp/Cylinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ struct Cylinder::State {
float theta;
float textureScaleX;
float textureScaleY;
float border;
vrb::Color borderColor;
vrb::Color solidColor;

State()
: textureWidth(0)
Expand All @@ -46,6 +49,7 @@ struct Cylinder::State {
, theta((float)M_PI)
, textureScaleX(1.0f)
, textureScaleY(1.0f)
, border(0.0f)
{}

void Initialize() {
Expand Down Expand Up @@ -77,8 +81,28 @@ struct Cylinder::State {
vrb::GeometryPtr geometry = vrb::Geometry::Create(create);
vrb::VertexArrayPtr array = vrb::VertexArray::Create(create);

for (int y = 0; y <= kHeightSegments; ++y) {
const float v = (float) y / (float) kHeightSegments;
const int ySegments = kHeightSegments + (border > 0.0f ? 2 : 0);

for (int y = 0; y <= ySegments; ++y) {
float offset = 0.0f;
float v = (float) y / (float) kHeightSegments;
vrb::Color vertexColor = solidColor;

if (border > 0) {
if (y == 0) {
v = 0.0f;
offset = border;
vertexColor = borderColor;
} else if (y == ySegments) {
v = 1.0f;
offset = -border;
vertexColor = borderColor;
} else {
v = (float) (y - 1) / (float) kHeightSegments;
}
}


for (int x = 0; x <= kRadialSegments; ++x) {
const float u = (float) x / (float) kRadialSegments;

Expand All @@ -91,7 +115,7 @@ struct Cylinder::State {
vrb::Vector normal;

vertex.x() = aRadius * cosTheta;
vertex.y() = -v * aHeight + aHeight * 0.5f;
vertex.y() = -v * aHeight + aHeight * 0.5f + offset;
vertex.z() = -aRadius * sinTheta;

uv.x() = u;
Expand All @@ -105,14 +129,17 @@ struct Cylinder::State {
array->AppendVertex(vertex);
array->AppendUV(uv);
array->AppendNormal(vertex.Normalize());
if (border > 0.0f) {
array->AppendColor(vertexColor);
}
}
}
geometry->SetVertexArray(array);

std::vector<int> indices;

for (int x = 0; x < kRadialSegments; ++x) {
for (int y = 0; y < kHeightSegments; ++y) {
for (int y = 0; y < ySegments; ++y) {
const int a = 1 + y * (kRadialSegments + 1) + x;
const int b = 1 + (y + 1) * (kRadialSegments + 1) + x;
const int c = 1 + (y + 1) * (kRadialSegments + 1) + x + 1;
Expand All @@ -131,6 +158,7 @@ struct Cylinder::State {

vrb::RenderStatePtr state = vrb::RenderState::Create(create);
state->SetLightsEnabled(false);
state->SetVertexColorEnabled(border > 0.0f);
state->SetFragmentPrecision(GL_HIGH_FLOAT);
state->SetUVTransformEnabled(true);
geometry->SetRenderState(state);
Expand All @@ -155,7 +183,7 @@ struct Cylinder::State {
if (segments % 2 != 0) {
segments++;
}
const int32_t indicesPerSegment = 6;
const int32_t indicesPerSegment = border > 0.0f ? 18 : 6;
const int32_t start = (kRadialSegments - segments) / 2;
geometry->SetRenderRange(start * indicesPerSegment, segments * indicesPerSegment);
}
Expand All @@ -172,6 +200,18 @@ Cylinder::Create(vrb::CreationContextPtr aContext, const float aRadius, const fl
return result;
}

CylinderPtr
Cylinder::Create(vrb::CreationContextPtr aContext, const float aRadius, const float aHeight, const vrb::Color& aSolidColor, const float aBorder, const vrb::Color& aBorderColor) {
CylinderPtr result = std::make_shared<vrb::ConcreteClass<Cylinder, Cylinder::State> >(aContext);
result->m.radius = aRadius;
result->m.height = aHeight;
result->m.solidColor = aSolidColor;
result->m.border = aBorder;
result->m.borderColor = aBorderColor;
result->m.Initialize();
return result;
}

CylinderPtr
Cylinder::Create(vrb::CreationContextPtr aContext, const VRLayerCylinderPtr& aLayer) {
CylinderPtr result = std::make_shared<vrb::ConcreteClass<Cylinder, Cylinder::State> >(aContext);
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/Cylinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef std::shared_ptr<Cylinder> CylinderPtr;
class Cylinder {
public:
static CylinderPtr Create(vrb::CreationContextPtr aContext, const float aRadius, const float aHeight, const VRLayerCylinderPtr& aLayer = nullptr);
static CylinderPtr Create(vrb::CreationContextPtr aContext, const float aRadius, const float aHeight, const vrb::Color& aSolidColor, const float kBorder, const vrb::Color& aBorderColor);
static CylinderPtr Create(vrb::CreationContextPtr aContext, const VRLayerCylinderPtr& aLayer = nullptr);
void GetTextureSize(int32_t& aWidth, int32_t& aHeight) const;
void SetTextureSize(int32_t aWidth, int32_t aHeight);
Expand Down
195 changes: 166 additions & 29 deletions app/src/main/cpp/WidgetResizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ struct ResizeBar;
typedef std::shared_ptr<ResizeBar> ResizeBarPtr;

static const float kBarSize = 0.04f;
#if defined(OCULUSVR)
static const float kBorder = 0.0f;
#else
static const float kBorder = kBarSize * 0.15f;
#endif
static const float kHandleRadius = 0.08f;
static const vrb::Vector kMinResize(1.5f, 1.5f, 0.0f);
static const vrb::Vector kMaxResize(8.0f, 4.5f, 0.0f);
Expand Down Expand Up @@ -60,18 +65,18 @@ struct ResizeBar {
Quad,
Cylinder
};
static ResizeBarPtr Create(vrb::CreationContextPtr& aContext, const vrb::Vector& aCenter, const vrb::Vector& aScale, const ResizeBar::Mode aMode) {
static ResizeBarPtr Create(vrb::CreationContextPtr& aContext, const vrb::Vector& aCenter, const vrb::Vector& aScale, const device::EyeRect& aBorder, const ResizeBar::Mode aMode) {
auto result = std::make_shared<ResizeBar>();
result->center = aCenter;
result->scale = aScale;
vrb::Vector max(kBarSize * 0.5f, kBarSize * 0.5f, 0.0f);
result->transform = vrb::Transform::Create(aContext);
if (aMode == ResizeBar::Mode::Cylinder) {
result->cylinder = Cylinder::Create(aContext, 1.0f, kBarSize);
result->cylinder = Cylinder::Create(aContext, 1.0f, kBarSize, vrb::Color(1.0f, 1.0f, 1.0f, 1.0f), kBorder, vrb::Color(1.0f, 1.0f, 1.0f, 0.0f));
result->cylinder->SetLightsEnabled(false);
result->transform->AddNode(result->cylinder->GetRoot());
} else {
result->geometry = Quad::CreateGeometry(aContext, -max, max);
result->geometry = CreateGeometry(aContext, -max, max, aBorder);
result->geometry->GetRenderState()->SetLightsEnabled(false);
result->transform->AddNode(result->geometry);
}
Expand All @@ -81,6 +86,90 @@ struct ResizeBar {
return result;
}

static void AppendBorder(const vrb::GeometryPtr& geometry, GLint index1, GLint index2, const vrb::Vector& offset, const vrb::Color& aColor, GLint& currentIndex) {
vrb::VertexArrayPtr array = geometry->GetVertexArray();
vrb::Vector offset1 = array->GetVertex(index1 - 1) + offset;
vrb::Vector offset2 = array->GetVertex(index2 - 1) + offset;
array->AppendVertex(offset1);
array->AppendVertex(offset2);
array->AppendColor(aColor);
array->AppendColor(aColor);

GLint index3 = currentIndex++;
GLint index4 = currentIndex++;
std::vector<int> index;
if (offset.y() > 0.0f) {
index = { index1, index2, index4, index3};
} else if (offset.y() < 0.0f) {
index = { index3, index4, index2, index1};
} else if (offset.x() > 0.0f) {
index = { index1, index3, index4, index2};
} else {
index = { index3, index1, index2, index4};
}

std::vector<int> normalIndex;
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);
geometry->AddFace(index, index, normalIndex);
}

static vrb::GeometryPtr CreateGeometry(vrb::CreationContextPtr aContext, const vrb::Vector &aMin, const vrb::Vector &aMax, const device::EyeRect& aBorder) {
vrb::VertexArrayPtr array = vrb::VertexArray::Create(aContext);
vrb::Color solid(1.0f, 1.0f, 1.0f, 1.0f);
vrb::Color border(1.0f, 1.0f, 1.0f, 0.0f);

const vrb::Vector bottomRight(aMax.x(), aMin.y(), aMin.z());
array->AppendVertex(aMin); // Bottom left
array->AppendVertex(bottomRight); // Bottom right
array->AppendVertex(aMax); // Top right
array->AppendVertex(vrb::Vector(aMin.x(), aMax.y(), aMax.z())); // Top left
for (int i = 0; i < 4; ++i) {
array->AppendColor(solid);
}

vrb::Vector normal = (bottomRight - aMin).Cross(aMax - aMin).Normalize();
array->AppendNormal(normal);

vrb::RenderStatePtr state = vrb::RenderState::Create(aContext);
state->SetVertexColorEnabled(true);
vrb::GeometryPtr geometry = vrb::Geometry::Create(aContext);
geometry->SetVertexArray(array);
geometry->SetRenderState(state);

std::vector<int> index;
index.push_back(1);
index.push_back(2);
index.push_back(3);
index.push_back(4);
std::vector<int> normalIndex;
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);

geometry->AddFace(index, index, normalIndex);

GLint currentIndex = 5;

if (aBorder.mX > 0.0f) {
AppendBorder(geometry, 1, 4, vrb::Vector(-aBorder.mX, 0.0f, 0.0f), border, currentIndex);
}
if (aBorder.mWidth > 0.0f) {
AppendBorder(geometry, 2, 3, vrb::Vector(aBorder.mWidth, 0.0f, 0.0f), border, currentIndex);
}
if (aBorder.mY > 0.0f) {
AppendBorder(geometry, 1, 2, vrb::Vector(0.0f, -aBorder.mY, 0.0f), border, currentIndex);
}
if (aBorder.mHeight > 0.0f) {
AppendBorder(geometry, 4, 3, vrb::Vector(0.0f, aBorder.mHeight, 0.0f), border, currentIndex);
}

return geometry;
}

void SetResizeState(ResizeState aState) {
if (resizeState != aState) {
resizeState = aState;
Expand Down Expand Up @@ -145,37 +234,80 @@ struct ResizeHandle {
array->AppendVertex(vrb::Vector(0.0f, 0.0f, 0.0f));
array->AppendNormal(vrb::Vector(0.0f, 0.0f, 1.0f));

std::vector<int> index;
std::vector<int> normalIndex;
vrb::Color solid(1.0f, 1.0f, 1.0f, 1.0f);
vrb::Color border(1.0f, 1.0f, 1.0f, 0.0f);
array->AppendColor(solid);

std::vector<int> indices;
std::vector<int> normalIndices;

const int kSides = 30;
double delta = 2.0 * M_PI / kSides;
for (int i = 0; i < kSides; ++i) {
const double angle = delta * i;
array->AppendVertex(vrb::Vector(kHandleRadius * (float)cos(angle), kHandleRadius * (float)sin(angle), 0.0f));
array->AppendColor(solid);
if (i > 0) {
index.push_back(1);
index.push_back(i + 1);
index.push_back(i + 2);
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);
indices.push_back(1);
indices.push_back(i + 1);
indices.push_back(i + 2);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);
}
}

index.push_back(1);
index.push_back(array->GetVertexCount());
index.push_back(2);
normalIndex.push_back(1);
normalIndex.push_back(1);
normalIndex.push_back(1);
indices.push_back(1);
indices.push_back(array->GetVertexCount());
indices.push_back(2);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);

vrb::GeometryPtr geometry = vrb::Geometry::Create(aContext);
vrb::RenderStatePtr state = vrb::RenderState::Create(aContext);
state->SetLightsEnabled(false);
state->SetVertexColorEnabled(true);
geometry->SetVertexArray(array);
geometry->SetRenderState(state);
geometry->AddFace(index, index, normalIndex);
geometry->AddFace(indices, indices, normalIndices);


if (kBorder > 0.0f) {
int lastCircleIndex = array->GetVertexCount();
int borderIndex = array->GetVertexCount() + 1;
for (int i = 0; i < kSides; ++i) {
const double angle = delta * i;
const float r = kHandleRadius + kBorder;
array->AppendVertex(vrb::Vector(r * (float)cos(angle), r * (float)sin(angle), 0.0f));
array->AppendColor(border);
if (i > 0) {
indices.clear();
normalIndices.clear();
indices.push_back(i + 2);
indices.push_back(i + 1);
indices.push_back(borderIndex);
indices.push_back(++borderIndex);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);
geometry->AddFace(indices, indices, normalIndices);
}
}
indices.clear();
normalIndices.clear();
indices.push_back(2);
indices.push_back(lastCircleIndex);
indices.push_back(borderIndex);
indices.push_back(lastCircleIndex + 1);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);
normalIndices.push_back(1);
geometry->AddFace(indices, indices, normalIndices);
}


return geometry;
}
Expand Down Expand Up @@ -223,15 +355,20 @@ struct WidgetResizer::State {

vrb::Vector horizontalSize(0.0f, 0.5f, 0.0f);
vrb::Vector verticalSize(0.5f, 0.0f, 0.0f);
device::EyeRect horizontalBorder(0.0f, kBorder, 0.0f, kBorder);
device::EyeRect verticalBorder(kBorder, 0.0f, kBorder, 0.0f);
ResizeBar::Mode mode = widget->GetCylinder() ? ResizeBar::Mode::Cylinder : ResizeBar::Mode::Quad;
ResizeBarPtr leftTop = CreateResizeBar(vrb::Vector(0.0f, 0.75f, 0.0f), horizontalSize, ResizeBar::Mode::Quad);
ResizeBarPtr leftBottom = CreateResizeBar(vrb::Vector(0.0f, 0.25f, 0.0f), horizontalSize, ResizeBar::Mode::Quad);
ResizeBarPtr rightTop = CreateResizeBar(vrb::Vector(1.0f, 0.75f, 0.0f), horizontalSize, ResizeBar::Mode::Quad);
ResizeBarPtr rightBottom = CreateResizeBar(vrb::Vector(1.0f, 0.25f, 0.0f), horizontalSize, ResizeBar::Mode::Quad);
ResizeBarPtr topLeft = CreateResizeBar(vrb::Vector(0.25f, 1.0f, 0.0f), verticalSize, mode);
ResizeBarPtr topRight = CreateResizeBar(vrb::Vector(0.75f, 1.0f, 0.0f), verticalSize, mode);
ResizeBarPtr bottomLeft = CreateResizeBar(vrb::Vector(0.25f, 0.0f, 0.0f), verticalSize, mode);
ResizeBarPtr bottomRight = CreateResizeBar(vrb::Vector(0.75f, 0.0f, 0.0f), verticalSize, mode);
ResizeBarPtr leftTop = CreateResizeBar(vrb::Vector(0.0f, 0.75f, 0.0f), horizontalSize, verticalBorder, ResizeBar::Mode::Quad);
ResizeBarPtr leftBottom = CreateResizeBar(vrb::Vector(0.0f, 0.25f, 0.0f), horizontalSize, verticalBorder, ResizeBar::Mode::Quad);
ResizeBarPtr rightTop = CreateResizeBar(vrb::Vector(1.0f, 0.75f, 0.0f), horizontalSize, verticalBorder, ResizeBar::Mode::Quad);
ResizeBarPtr rightBottom = CreateResizeBar(vrb::Vector(1.0f, 0.25f, 0.0f), horizontalSize, verticalBorder, ResizeBar::Mode::Quad);
ResizeBarPtr topLeft = CreateResizeBar(vrb::Vector(0.25f, 1.0f, 0.0f), verticalSize, horizontalBorder, mode);
ResizeBarPtr topRight = CreateResizeBar(vrb::Vector(0.75f, 1.0f, 0.0f), verticalSize, horizontalBorder, mode);
//ResizeBarPtr bottomLeft = CreateResizeBar(vrb::Vector(0.25f, 0.0f, 0.0f), verticalSize, mode);
//ResizeBarPtr bottomRight = CreateResizeBar(vrb::Vector(0.75f, 0.0f, 0.0f), verticalSize, mode);
ResizeBarPtr bottom = CreateResizeBar(vrb::Vector(0.5f, 0.0f, 0.0f), vrb::Vector(1.0f, 0.0f, 0.0f), horizontalBorder, mode);
//ResizeBarPtr bottomLeftCorner = CreateResizeBar(vrb::Vector(0.0f, 0.0f, 0.0f), vrb::Vector(0.0f, 0.0f, 0.0f), device::EyeRect(kBorder, kBorder, 0.0f, 0.0f), ResizeBar::Mode::Quad);
//ResizeBarPtr bottomRightCorner = CreateResizeBar(vrb::Vector(1.0f, 0.0f, 0.0f), vrb::Vector(0.0f, 0.0f, 0.0f), device::EyeRect(.0f, 0.0f, kBorder, kBorder), ResizeBar::Mode::Quad);

CreateResizeHandle(vrb::Vector(0.0f, 1.0f, 0.0f), ResizeHandle::ResizeMode::Both, {leftTop, topLeft});
CreateResizeHandle(vrb::Vector(1.0f, 1.0f, 0.0f), ResizeHandle::ResizeMode::Both, {rightTop, topRight});
Expand All @@ -245,12 +382,12 @@ struct WidgetResizer::State {
Layout();
}

ResizeBarPtr CreateResizeBar(const vrb::Vector& aCenter, vrb::Vector aScale, const ResizeBar::Mode aMode) {
ResizeBarPtr CreateResizeBar(const vrb::Vector& aCenter, vrb::Vector aScale, const device::EyeRect& aBorder, const ResizeBar::Mode aMode) {
vrb::CreationContextPtr create = context.lock();
if (!create) {
return nullptr;
}
ResizeBarPtr result = ResizeBar::Create(create, aCenter, aScale, aMode);
ResizeBarPtr result = ResizeBar::Create(create, aCenter, aScale, aBorder, aMode);
resizeBars.push_back(result);
root->AddNode(result->transform);
return result;
Expand Down Expand Up @@ -329,7 +466,7 @@ struct WidgetResizer::State {
const float pointerAngle = (float)M_PI * 0.5f + theta * 0.5f - theta * bar->center.x();
vrb::Matrix rotation = vrb::Matrix::Rotation(vrb::Vector(-cosf(pointerAngle), 0.0f, sinf(pointerAngle)));
if (bar->cylinder) {
bar->cylinder->SetCylinderTheta(theta * 0.5f);
bar->cylinder->SetCylinderTheta(theta * bar->scale.x());
vrb::Matrix translation = vrb::Matrix::Position(vrb::Vector(0.0f, min.y() + height * bar->center.y(), radius));
vrb::Matrix scale = vrb::Matrix::Identity();
scale.ScaleInPlace(vrb::Vector(radius, 1.0f, radius));
Expand Down