Skip to content
Permalink
Browse files

[3d] Fix creation of extruded walls in vertex binding mode

Previously the walls always had horizontal top/bottom, but
in vertex binding mode the walls need to have different z values
at the start and end coordinate

Note that the unit test exposes a different bug in the tesselator,
which should also be fixed...
  • Loading branch information
nyalldawson authored and wonder-sk committed Nov 23, 2017
1 parent 134065d commit 5206bf0f769d13d976c7988f98e0337ed5a13a81
Showing with 39 additions and 13 deletions.
  1. +11 −9 src/3d/qgstessellator.cpp
  2. +28 −4 tests/src/3d/testqgstessellator.cpp
@@ -27,7 +27,7 @@
#include <QVector3D>
#include <algorithm>

static void make_quad( float x0, float y0, float x1, float y1, float zLow, float zHigh, QVector<float> &data, bool addNormals )
static void make_quad( float x0, float y0, float z0, float x1, float y1, float z1, float height, QVector<float> &data, bool addNormals )
{
float dx = x1 - x0;
float dy = -( y1 - y0 );
@@ -37,24 +37,24 @@ static void make_quad( float x0, float y0, float x1, float y1, float zLow, float
vn.normalize();

// triangle 1
data << x0 << zHigh << -y0;
data << x0 << z0 + height << -y0;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();
data << x1 << zHigh << -y1;
data << x1 << z1 + height << -y1;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();
data << x0 << zLow << -y0;
data << x0 << z0 << -y0;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();

// triangle 2
data << x0 << zLow << -y0;
data << x0 << z0 << -y0;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();
data << x1 << zHigh << -y1;
data << x1 << z1 + height << -y1;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();
data << x1 << zLow << -y1;
data << x1 << z1 << -y1;
if ( addNormals )
data << vn.x() << vn.y() << vn.z();
}
@@ -104,9 +104,11 @@ static void _makeWalls( const QgsCurve &ring, bool ccw, float extrusionHeight, Q
ring.pointAt( is_counter_clockwise == ccw ? i : ring.numPoints() - i - 1, pt, vt );
float x0 = ptPrev.x() - originX, y0 = ptPrev.y() - originY;
float x1 = pt.x() - originX, y1 = pt.y() - originY;
float height = pt.z();
float z0 = ptPrev.z();
float z1 = pt.z();

// make a quad
make_quad( x0, y0, x1, y1, height, height + extrusionHeight, data, addNormals );
make_quad( x0, y0, z0, x1, y1, z1, extrusionHeight, data, addNormals );
ptPrev = pt;
}
}
@@ -107,20 +107,18 @@ class TestQgsTessellator : public QObject
{
Q_OBJECT
public:
TestQgsTessellator();
TestQgsTessellator() = default;

private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.

void testBasic();
void testWalls();

private:
};

TestQgsTessellator::TestQgsTessellator() = default;


//runs before all tests
void TestQgsTessellator::initTestCase()
{
@@ -169,6 +167,32 @@ void TestQgsTessellator::testBasic()
QVERIFY( checkTriangleOutput( tNZ.data(), true, tcNormals ) );
}

void TestQgsTessellator::testWalls()
{
QgsPolygon polygonZ;
polygonZ.fromWkt( "POLYGONZ((1 1 1, 2 1 2, 3 2 3, 1 2 4, 1 1 1))" );

QList<TriangleCoords> tc;

// NOTE - these coordinates are wrong, and this test exposes a different bug in the tesselator
// 2.4 should be 2:
tc << TriangleCoords( QVector3D( 1, 2.4, 14 ), QVector3D( 2, 1.4, 12 ), QVector3D( 3, 2, 13 ) );
tc << TriangleCoords( QVector3D( 1, 2.4, 14 ), QVector3D( 1, 1, 11 ), QVector3D( 2, 1.4, 12 ) );

tc << TriangleCoords( QVector3D( 1, 1, 11 ), QVector3D( 1, 2, 14 ), QVector3D( 1, 1, 1 ) );
tc << TriangleCoords( QVector3D( 1, 1, 1 ), QVector3D( 1, 2, 14 ), QVector3D( 1, 2, 4 ) );
tc << TriangleCoords( QVector3D( 1, 2, 14 ), QVector3D( 3, 2, 13 ), QVector3D( 1, 2, 4 ) );
tc << TriangleCoords( QVector3D( 1, 2, 4 ), QVector3D( 3, 2, 13 ), QVector3D( 3, 2, 3 ) );
tc << TriangleCoords( QVector3D( 3, 2, 13 ), QVector3D( 2, 1, 12 ), QVector3D( 3, 2, 3 ) );
tc << TriangleCoords( QVector3D( 3, 2, 3 ), QVector3D( 2, 1, 12 ), QVector3D( 2, 1, 2 ) );
tc << TriangleCoords( QVector3D( 2, 1, 12 ), QVector3D( 1, 1, 11 ), QVector3D( 2, 1, 2 ) );
tc << TriangleCoords( QVector3D( 2, 1, 2 ), QVector3D( 1, 1, 11 ), QVector3D( 1, 1, 1 ) );

QgsTessellator tZ( 0, 0, false );
tZ.addPolygon( polygonZ, 10 );
QVERIFY( checkTriangleOutput( tZ.data(), false, tc ) );
}


QGSTEST_MAIN( TestQgsTessellator )
#include "testqgstessellator.moc"

0 comments on commit 5206bf0

Please sign in to comment.
You can’t perform that action at this time.