mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 20:21:24 -06:00
Using NURBS to interpolate patch vertex positions.
This commit is contained in:
@@ -50,7 +50,7 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
ClipMapGlobe::ClipMapGlobe(const ghoul::Dictionary& dictionary)
|
||||
: _patch(10, 10, 0, 0, M_PI / 6, M_PI / 6)
|
||||
: _patch(20, 20, 0, 0, M_PI / 4, M_PI / 4)
|
||||
, _rotation("rotation", "Rotation", 0, 0, 360)
|
||||
{
|
||||
std::string name;
|
||||
|
||||
@@ -168,7 +168,7 @@ void Geometry::drawUsingActiveProgram() {
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementBufferID);
|
||||
glDrawElements(GL_TRIANGLES, _elementData.size(), GL_UNSIGNED_INT, 0);
|
||||
glDrawElements(GL_LINES, _elementData.size(), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,36 +112,48 @@ namespace openspace {
|
||||
// TODO : Need to get the radius of the globe
|
||||
double r = 6e6;
|
||||
|
||||
// Create control points (double)
|
||||
glm::dvec3 p00, p01, p10, p11;
|
||||
// Create control points and normals(double)
|
||||
glm::dvec3 p00, p01, p02, p10, p11, p12, p20, p21, p22;
|
||||
glm::dvec3 n00, n01, n02, n10, n11, n12, n20, n21, n22;
|
||||
|
||||
// Calculate global positions of control points
|
||||
p00 = glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x - _sizeLatLon.x,
|
||||
_posLatLon.y - _sizeLatLon.y,
|
||||
r));
|
||||
p10 = glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x + _sizeLatLon.x,
|
||||
_posLatLon.y - _sizeLatLon.y,
|
||||
r));
|
||||
p01 = glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x - _sizeLatLon.x,
|
||||
_posLatLon.y + _sizeLatLon.y,
|
||||
r));
|
||||
p11 = glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x + _sizeLatLon.x,
|
||||
_posLatLon.y + _sizeLatLon.y,
|
||||
r));
|
||||
// Calculate positions of corner control points
|
||||
p00 = calculateCornerPointLeftBottom();
|
||||
p20 = calculateCornerPointRightBottom();
|
||||
p02 = calculateCornerPointLeftTop();
|
||||
p22 = calculateCornerPointRightTop();
|
||||
// Get position of center control points
|
||||
p01 = calculateCenterPoint(p00, p02);
|
||||
p21 = calculateCenterPoint(p20, p22);
|
||||
p10 = calculateCenterPoint(p00, p20);
|
||||
p12 = calculateCenterPoint(p02, p22);
|
||||
p11 = calculateCenterPoint(p01, p21);
|
||||
|
||||
// Calculate normals from control point positions
|
||||
n00 = normalize(p00);
|
||||
n01 = normalize(p01);
|
||||
n02 = normalize(p02);
|
||||
n10 = normalize(p10);
|
||||
n11 = normalize(p11);
|
||||
n12 = normalize(p12);
|
||||
n20 = normalize(p20);
|
||||
n21 = normalize(p21);
|
||||
n22 = normalize(p22);
|
||||
|
||||
// TODO : Transformation to world space from model space should also consider
|
||||
// rotations. Now it only uses translatation for simplicity. Should be done
|
||||
// With a matrix transform
|
||||
// TODO : Normals should also be transformed
|
||||
glm::dvec3 position = data.position.dvec3();
|
||||
p00 += position;
|
||||
p10 += position;
|
||||
p20 += position;
|
||||
p01 += position;
|
||||
p11 += position;
|
||||
|
||||
p21 += position;
|
||||
p02 += position;
|
||||
p12 += position;
|
||||
p22 += position;
|
||||
|
||||
// Calculate global position of camera
|
||||
// TODO : Should only need to fetch the camera transform and use directly
|
||||
// Now the viewTransform is wrong due to the constant lookUpVector
|
||||
@@ -155,19 +167,48 @@ namespace openspace {
|
||||
// Transform control points to camera space
|
||||
p00 = glm::dvec3(viewTransform * glm::dvec4(p00, 1.0));
|
||||
p10 = glm::dvec3(viewTransform * glm::dvec4(p10, 1.0));
|
||||
p20 = glm::dvec3(viewTransform * glm::dvec4(p20, 1.0));
|
||||
p01 = glm::dvec3(viewTransform * glm::dvec4(p01, 1.0));
|
||||
p11 = glm::dvec3(viewTransform * glm::dvec4(p11, 1.0));
|
||||
p21 = glm::dvec3(viewTransform * glm::dvec4(p21, 1.0));
|
||||
p02 = glm::dvec3(viewTransform * glm::dvec4(p02, 1.0));
|
||||
p12 = glm::dvec3(viewTransform * glm::dvec4(p12, 1.0));
|
||||
p22 = glm::dvec3(viewTransform * glm::dvec4(p22, 1.0));
|
||||
|
||||
// Send control points to GPU to be used in shader
|
||||
// TODO : Will need more control points or possibly normals to be able to
|
||||
// do better than linear interpolation
|
||||
// Transform normals to camera space
|
||||
n00 = glm::dvec3(viewTransform * glm::dvec4(n00, 0.0));
|
||||
n10 = glm::dvec3(viewTransform * glm::dvec4(n10, 0.0));
|
||||
n20 = glm::dvec3(viewTransform * glm::dvec4(n20, 0.0));
|
||||
n01 = glm::dvec3(viewTransform * glm::dvec4(n01, 0.0));
|
||||
n11 = glm::dvec3(viewTransform * glm::dvec4(n11, 0.0));
|
||||
n21 = glm::dvec3(viewTransform * glm::dvec4(n21, 0.0));
|
||||
n02 = glm::dvec3(viewTransform * glm::dvec4(n02, 0.0));
|
||||
n12 = glm::dvec3(viewTransform * glm::dvec4(n12, 0.0));
|
||||
n22 = glm::dvec3(viewTransform * glm::dvec4(n22, 0.0));
|
||||
|
||||
// Send control points and normals to GPU to be used in shader
|
||||
_programObject->setUniform("p00", glm::vec3(p00));
|
||||
_programObject->setUniform("p10", glm::vec3(p10));
|
||||
_programObject->setUniform("p20", glm::vec3(p20));
|
||||
_programObject->setUniform("p01", glm::vec3(p01));
|
||||
_programObject->setUniform("p11", glm::vec3(p11));
|
||||
_programObject->setUniform("p21", glm::vec3(p21));
|
||||
_programObject->setUniform("p02", glm::vec3(p02));
|
||||
_programObject->setUniform("p12", glm::vec3(p12));
|
||||
_programObject->setUniform("p22", glm::vec3(p22));
|
||||
|
||||
_programObject->setUniform("n00", glm::vec3(n00));
|
||||
_programObject->setUniform("n10", glm::vec3(n10));
|
||||
_programObject->setUniform("n20", glm::vec3(n20));
|
||||
_programObject->setUniform("n01", glm::vec3(n01));
|
||||
_programObject->setUniform("n11", glm::vec3(n11));
|
||||
_programObject->setUniform("n21", glm::vec3(n21));
|
||||
_programObject->setUniform("n02", glm::vec3(n02));
|
||||
_programObject->setUniform("n12", glm::vec3(n12));
|
||||
_programObject->setUniform("n22", glm::vec3(n22));
|
||||
|
||||
_programObject->setUniform("Projection", data.camera.projectionMatrix());
|
||||
|
||||
|
||||
// Render triangles (use texture coordinates to interpolate to new positions)
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glCullFace(GL_BACK);
|
||||
@@ -187,4 +228,50 @@ namespace openspace {
|
||||
_posLatLon = posLatLon;
|
||||
}
|
||||
|
||||
glm::dvec3 LatLonPatch::calculateCornerPointLeftBottom() {
|
||||
double r = 6e6; // TODO : DEFINE r AS A MEMBER VARIABLE
|
||||
|
||||
return glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x - _sizeLatLon.x,
|
||||
_posLatLon.y - _sizeLatLon.y,
|
||||
r));
|
||||
}
|
||||
glm::dvec3 LatLonPatch::calculateCornerPointRightBottom() {
|
||||
double r = 6e6; // TODO : DEFINE r AS A MEMBER VARIABLE
|
||||
|
||||
return glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x + _sizeLatLon.x,
|
||||
_posLatLon.y - _sizeLatLon.y,
|
||||
r));
|
||||
}
|
||||
glm::dvec3 LatLonPatch::calculateCornerPointLeftTop() {
|
||||
double r = 6e6; // TODO : DEFINE r AS A MEMBER VARIABLE
|
||||
|
||||
return glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x - _sizeLatLon.x,
|
||||
_posLatLon.y + _sizeLatLon.y,
|
||||
r));
|
||||
}
|
||||
glm::dvec3 LatLonPatch::calculateCornerPointRightTop() {
|
||||
double r = 6e6; // TODO : DEFINE r AS A MEMBER VARIABLE
|
||||
|
||||
return glm::dvec3(converter::latLonToCartesian(
|
||||
_posLatLon.x + _sizeLatLon.x,
|
||||
_posLatLon.y + _sizeLatLon.y,
|
||||
r));
|
||||
}
|
||||
|
||||
glm::dvec3 LatLonPatch::calculateCenterPoint(glm::dvec3 p0, glm::dvec3 p2) {
|
||||
glm::dvec3 n0 = glm::normalize(p0);
|
||||
glm::dvec3 n2 = glm::normalize(p2);
|
||||
|
||||
// Solution derived
|
||||
glm::dvec2 u = glm::dvec2(0, glm::dot(p2, n2) - glm::dot(p0, n2));
|
||||
double cosNormalAngle = glm::dot(n0, n2);
|
||||
glm::dmat2 A = glm::dmat2({ 1, cosNormalAngle, cosNormalAngle, 1 });
|
||||
glm::dvec2 stParam = glm::inverse(A) * u;
|
||||
glm::dvec3 p1 = p0 + stParam.s * n0 + stParam.t * n2;
|
||||
return p1;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -61,6 +61,17 @@ namespace openspace {
|
||||
|
||||
void setPositionLatLon(glm::dvec2 posLatLon);
|
||||
|
||||
|
||||
glm::dvec3 calculateCornerPointLeftBottom();
|
||||
glm::dvec3 calculateCornerPointRightBottom();
|
||||
glm::dvec3 calculateCornerPointLeftTop();
|
||||
glm::dvec3 calculateCornerPointRightTop();
|
||||
|
||||
/**
|
||||
Finds a third control point between the two parameter points assuming
|
||||
they both lie on a sphere with the origin in the center.
|
||||
*/
|
||||
glm::dvec3 calculateCenterPoint(glm::dvec3 p0, glm::dvec3 p2);
|
||||
private:
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;
|
||||
|
||||
|
||||
@@ -28,8 +28,23 @@ uniform mat4 Projection;
|
||||
|
||||
uniform vec3 p00;
|
||||
uniform vec3 p10;
|
||||
uniform vec3 p20;
|
||||
uniform vec3 p01;
|
||||
uniform vec3 p11;
|
||||
uniform vec3 p21;
|
||||
uniform vec3 p02;
|
||||
uniform vec3 p12;
|
||||
uniform vec3 p22;
|
||||
|
||||
uniform vec3 n00;
|
||||
uniform vec3 n10;
|
||||
uniform vec3 n20;
|
||||
uniform vec3 n01;
|
||||
uniform vec3 n11;
|
||||
uniform vec3 n21;
|
||||
uniform vec3 n02;
|
||||
uniform vec3 n12;
|
||||
uniform vec3 n22;
|
||||
|
||||
layout(location = 1) in vec2 in_UV;
|
||||
|
||||
@@ -37,12 +52,135 @@ out vec4 vs_position;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void nurbsBasis(int c, float t, int npts, int x[7], inout float n[4])
|
||||
{
|
||||
int nplusc;
|
||||
int i,k;
|
||||
float d, e;
|
||||
float temp[36];
|
||||
|
||||
nplusc = npts + c;
|
||||
|
||||
/* calculate the first order basis functions n[i][1] */
|
||||
|
||||
for (i = 1; i<= nplusc-1; i++){
|
||||
if (( t >= x[i]) && (t < x[i+1]))
|
||||
temp[i] = 1;
|
||||
else
|
||||
temp[i] = 0;
|
||||
}
|
||||
|
||||
/* calculate the higher order basis functions */
|
||||
|
||||
for (k = 2; k <= c; k++){
|
||||
for (i = 1; i <= nplusc-k; i++){
|
||||
if (temp[i] != 0) /* if the lower order basis function is zero skip the calculation */
|
||||
d = ((t-x[i])*temp[i])/(x[i+k-1]-x[i]);
|
||||
else
|
||||
d = 0;
|
||||
|
||||
if (temp[i+1] != 0) /* if the lower order basis function is zero skip the calculation */
|
||||
e = ((x[i+k]-t)*temp[i+1])/(x[i+k]-x[i+1]);
|
||||
else
|
||||
e = 0;
|
||||
|
||||
temp[i] = d + e;
|
||||
}
|
||||
}
|
||||
|
||||
float floatXnplusc = x[nplusc];
|
||||
if (t == floatXnplusc){ /* pick up last point */
|
||||
temp[npts] = 1;
|
||||
}
|
||||
|
||||
/* put in n array */
|
||||
|
||||
for (i = 1; i <= npts; i++) {
|
||||
n[i] = temp[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void getKnots(int n, int c, inout int x[7])
|
||||
{
|
||||
int nplusc, nplus2, i;
|
||||
|
||||
nplusc = n + c;
|
||||
nplus2 = n + 2;
|
||||
|
||||
x[1] = 0;
|
||||
for (i = 2; i <= nplusc; i++){
|
||||
if ( (i > c) && (i < nplus2) )
|
||||
x[i] = x[i-1] + 1;
|
||||
else
|
||||
x[i] = x[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
// Bilinear interpolation
|
||||
vec3 p0 = (1 - in_UV.x) * p00 + in_UV.x * p10;
|
||||
vec3 p1 = (1 - in_UV.x) * p01 + in_UV.x * p11;
|
||||
vec3 p = (1 - in_UV.y) * p0 + in_UV.y * p1;
|
||||
/*
|
||||
vec3 p0 = (1 - in_UV.x) * p00 + in_UV.x * p20;
|
||||
vec3 p2 = (1 - in_UV.x) * p02 + in_UV.x * p22;
|
||||
vec3 p = (1 - in_UV.y) * p0 + in_UV.y * p2;
|
||||
*/
|
||||
|
||||
// Calculate three weights
|
||||
// These values of the weights will make the curves in to circle segments
|
||||
|
||||
|
||||
float w10 = dot(n00, normalize(n00 + n20));
|
||||
float w11 = dot(n01, normalize(n01 + n21));
|
||||
float w12 = dot(n02, normalize(n02 + n22));
|
||||
|
||||
float basisFunctionValues[4];
|
||||
int order = 3; // Order of the NURBS curve
|
||||
int npts = 3; // Number of control points
|
||||
int knotVector[7] = {0,0,0,0,1,1,1};
|
||||
|
||||
// Interpolate in u direction
|
||||
// getKnots(npts, order, knotVector);
|
||||
nurbsBasis(order, in_UV.x, npts, knotVector, basisFunctionValues);
|
||||
vec3 p0 =
|
||||
basisFunctionValues[1] * p00 +
|
||||
basisFunctionValues[2] * p10 * w10 +
|
||||
basisFunctionValues[3] * p20;
|
||||
vec3 p1 =
|
||||
basisFunctionValues[1] * p01 +
|
||||
basisFunctionValues[2] * p11 * w11 +
|
||||
basisFunctionValues[3] * p21;
|
||||
vec3 p2 =
|
||||
basisFunctionValues[1] * p02 +
|
||||
basisFunctionValues[2] * p12 * w12 +
|
||||
basisFunctionValues[3] * p22;
|
||||
|
||||
// Interpolate normals
|
||||
vec3 n0 =
|
||||
basisFunctionValues[1] * n00 +
|
||||
basisFunctionValues[2] * n10 * w10 +
|
||||
basisFunctionValues[3] * n20;
|
||||
vec3 n1 =
|
||||
basisFunctionValues[1] * n01 +
|
||||
basisFunctionValues[2] * n11 * w11 +
|
||||
basisFunctionValues[3] * n21;
|
||||
vec3 n2 =
|
||||
basisFunctionValues[1] * n02 +
|
||||
basisFunctionValues[2] * n12 * w12 +
|
||||
basisFunctionValues[3] * n22;
|
||||
|
||||
// Calculate the last weight
|
||||
float w1 = dot(n0, n1);
|
||||
|
||||
// Interpolate in v direction
|
||||
nurbsBasis(order, in_UV.y, npts, knotVector, basisFunctionValues);
|
||||
vec3 p =
|
||||
basisFunctionValues[1] * p0 +
|
||||
basisFunctionValues[2] * p1 * w1 +
|
||||
basisFunctionValues[3] * p2;
|
||||
|
||||
//p = (1 - in_UV.y) * p0 + in_UV.y * p2;
|
||||
|
||||
|
||||
vec4 position = Projection * vec4(p, 1);
|
||||
gl_Position = z_normalization(position);
|
||||
|
||||
Reference in New Issue
Block a user