Example #1
0
void TerrainPageGeometry::blitSegmentToOgre(float* ogreHeightData, Mercator::Segment& segment, int startX, int startY)
{
	int segmentWidth = segment.getSize();
	int i, j;
	int pageWidth = mPage.getPageSize();
	size_t ogreDataSize = pageWidth * pageWidth;

	const float* sourcePtr = segment.getPoints();
	float* destPtr = ogreHeightData;

	float* dataEnd = ogreHeightData + ogreDataSize;

	float* end = destPtr + (pageWidth * ((segmentWidth - 1) + startY)) + (((segmentWidth - 1) + startX));

	float* tempPtr = end;
	for (i = 0; i < segmentWidth; ++i) {
		tempPtr -= segmentWidth;
		for (j = 0; j < segmentWidth; ++j) {

			if (tempPtr >= ogreHeightData && tempPtr < dataEnd) {
				*(tempPtr) = *(sourcePtr + j);
			}
			tempPtr += 1;
		}
		tempPtr -= pageWidth;
		sourcePtr += segmentWidth;
	}
}
void testDepthShader()
{
    Mercator::Terrain terrain(Mercator::Terrain::SHADED, 16);

    Mercator::Shader::Parameters params;
    params[Mercator::DepthShader::key_waterLevel] = 0.f;
    params[Mercator::DepthShader::key_murkyDepth] = -12.f;
    
    Mercator::DepthShader* dshade = new Mercator::DepthShader();
    delete dshade;
    dshade = new Mercator::DepthShader(params);
    terrain.addShader(dshade, 0);
    
    terrain.setBasePoint(0, 0, -20);
    terrain.setBasePoint(0, 1, 1);
    terrain.setBasePoint(1, 0, 2);
    terrain.setBasePoint(1, 1, 0.5);
    terrain.setBasePoint(2, 0, 2);
    terrain.setBasePoint(2, 1, 0.5);
    
    Mercator::Segment* seg = terrain.getSegment(0,0);
    
    seg->populateSurfaces();
    seg->populate();
    seg->populateSurfaces();

    seg = terrain.getSegment(1,0);
    dshade->checkIntersect(*seg);
}
void testAreaShader()
{
    Mercator::Area* a1 = new Mercator::Area(1, false);
    
    WFMath::Polygon<2> p;
    p.addCorner(p.numCorners(), Point2(3, 4));
    p.addCorner(p.numCorners(), Point2(10, 10));
    p.addCorner(p.numCorners(), Point2(14, 6));
    p.addCorner(p.numCorners(), Point2(18, 4));
    p.addCorner(p.numCorners(), Point2(17, 19));
    p.addCorner(p.numCorners(), Point2(6, 20));
    p.addCorner(p.numCorners(), Point2(-1, 18));
    p.addCorner(p.numCorners(), Point2(-8, 11));
    
    a1->setShape(p);
    
    Mercator::Terrain terrain(Mercator::Terrain::SHADED, 16);
    
    Mercator::AreaShader* ashade = new Mercator::AreaShader(1);
    terrain.addShader(ashade, 0);
    
    terrain.setBasePoint(0, 0, -1);
    terrain.setBasePoint(0, 1, 8);
    terrain.setBasePoint(1, 0, 2);
    terrain.setBasePoint(1, 1, 11);
    
    terrain.addArea(a1);
    
    Mercator::Segment* seg = terrain.getSegment(0,0);
    assert(a1->checkIntersects(*seg));
    
    seg->populateSurfaces();
}
Example #4
0
void SegmentManager::addSegment(Mercator::Segment& segment)
{
	std::stringstream ss;
	ss << (segment.getXRef() / segment.getResolution()) << "_" << (segment.getYRef() / segment.getResolution());
	std::unique_lock<std::mutex> l(mSegmentsMutex);
	SegmentStore::const_iterator I = mSegments.find(ss.str());
	if (I == mSegments.end()) {
		mSegments.insert(SegmentStore::value_type(ss.str(), new SegmentHolder(new Segment(segment), *this)));
	}
}
Example #5
0
void testAreaShader()
{
    Mercator::Area* a1 = new Mercator::Area(1, false);
    
    WFMath::Polygon<2> p;
    p.addCorner(p.numCorners(), Point2(3, 4));
    p.addCorner(p.numCorners(), Point2(10, 10));
    p.addCorner(p.numCorners(), Point2(14, 6));
    p.addCorner(p.numCorners(), Point2(18, 4));
    p.addCorner(p.numCorners(), Point2(17, 19));
    p.addCorner(p.numCorners(), Point2(6, 20));
    p.addCorner(p.numCorners(), Point2(-1, 18));
    p.addCorner(p.numCorners(), Point2(-8, 11));
    
    a1->setShape(p);
    
    Mercator::Area* a2 = new Mercator::Area(1, false);
    
    WFMath::Polygon<2> p2;
    p2.addCorner(p2.numCorners(), Point2(25, 18));
    p2.addCorner(p2.numCorners(), Point2(72, 22));
    p2.addCorner(p2.numCorners(), Point2(60, 30));
    p2.addCorner(p2.numCorners(), Point2(27, 28));
    p2.addCorner(p2.numCorners(), Point2(25, 45));
    p2.addCorner(p2.numCorners(), Point2(3, 41));
    p2.addCorner(p2.numCorners(), Point2(-2, 20));
    a2->setShape(p2);
    
    Mercator::Terrain terrain(Mercator::Terrain::SHADED, 16);
    
    Mercator::Shader * base_shader =
          new Mercator::FillShader(Mercator::Shader::Parameters());
    terrain.addShader(base_shader, 0);

    Mercator::AreaShader* ashade = new Mercator::AreaShader(1);
    terrain.addShader(ashade, 1);
    
    terrain.setBasePoint(0, 0, -1);
    terrain.setBasePoint(0, 1, 8);
    terrain.setBasePoint(1, 0, 2);
    terrain.setBasePoint(1, 1, 11);
    terrain.setBasePoint(2, 0, 2);
    terrain.setBasePoint(2, 1, 11);
    
    terrain.addArea(a1);
   // terrain.addArea(a2);
    
    Mercator::Segment* seg = terrain.getSegment(0,0);
    assert(a1->checkIntersects(*seg));
    
    seg->populateSurfaces();
    writePGMForSurface("test1.pgm", seg->getSize(), seg->getSurfaces()[1]);
    
    
    seg = terrain.getSegment(1,0);    
    seg->populateSurfaces();
    writePGMForSurface("test2.pgm", seg->getSize(), seg->getSurfaces()[1]);
}
Example #6
0
int main() 
{
    int size = 64;
    Mercator::Segment *s = new Mercator::Segment(0, 0, size);

    Mercator::Matrix<2, 2, Mercator::BasePoint> & base = s->getControlPoints();
    base[0] = Mercator::BasePoint(10.f, 3.f);
    base[1].height() = 15.f;
    base[2] = Mercator::BasePoint(10.f, 10.f);
    base[3] = Mercator::BasePoint(9.32f, 1.9f);
    
    s->populate();
/*    s->populateNormals(); 

    float *n=s->getNormals();
i*/    //for (int i=0; i<=size; ++i) {
        int i=0;
        for (int j=0; j<=size; ++j) {
                std::cout <<  j << ":" << s->get(i,j) << ", " ;
        }
       //}
/*          std::cout << s->get(i,j) << " ; ";
            std::cout << n[j * size * 3 + i * 3 ] << " : ";
            std::cout << n[j * size * 3 + i * 3 + 1] << " : ";
            std::cout << n[j * size * 3 + i * 3 + 2];
            std::cout << std::endl;
        }
            std::cout << std::endl;
    }
*/

    Mercator::Terrain t;
    t.setBasePoint(0,0,10.0);
    t.setBasePoint(0,1,12.0);
    t.setBasePoint(1,0,14.0);
    t.setBasePoint(1,1,16.0);
    std::cout << t.getSegmentAtIndex(0,0);
    t.setBasePoint(1,1,12.0);
    std::cout << t.getSegmentAtIndex(0,0);
    std::cout << std::endl;
    
    return 0;
}
Example #7
0
void TerrainPageSurfaceLayer::fillImage(const TerrainPageGeometry& geometry, Image& image, unsigned int channel) const
{
	SegmentVector validSegments = geometry.getValidSegments();
	for (SegmentVector::const_iterator I = validSegments.begin(); I != validSegments.end(); ++I) {
		Mercator::Segment* segment = I->segment;
		if (mShader.checkIntersect(*segment)) {
			Mercator::Surface* surface = getSurfaceForSegment(segment);
			if (surface && surface->isValid()) {
				Image::ImageBuffer* textureBitmap = new Image::ImageBuffer(segment->getResolution(), 1);
				auto srcPtr = surface->getData();
				auto dataPtr = textureBitmap->getData();
				auto segmentSize = segment->getSize();
				for (int i = 0; i < segment->getResolution(); ++i) {
					for (int j = 0; j < segment->getResolution(); ++j) {
						//interpolate four samples to get the fragment coverage
						*dataPtr = (unsigned char)((srcPtr[(i * segmentSize) + j] + srcPtr[(i * segmentSize) + j + 1] + srcPtr[((i + 1) * segmentSize) + j] + srcPtr[((i + 1) * segmentSize) + j + 1]) / 4);
						dataPtr++;
					}
				}

				WFImage sourceImage(textureBitmap);
				image.blit(sourceImage, channel, ((int)I->index.x() * segment->getResolution()), ((mTerrainPageSurface.getNumberOfSegmentsPerAxis() - (int)I->index.y() - 1) * segment->getResolution()));
			}
		}
	}
}
Example #8
0
void TerrainPageGeometry::blitSegmentToOgre(float* ogreHeightData, Mercator::Segment& segment, int startX, int startY)
{
	int segmentWidth = segment.getSize();
	int pageWidth = mPage.getPageSize();
	size_t ogreDataSize = pageWidth * pageWidth;

	const float* sourcePtr = segment.getPoints();
	float* destPtr = ogreHeightData;

	float* dataEnd = ogreHeightData + ogreDataSize;
	
	// copy points line-by line
	float* tempPtr = destPtr + pageWidth * startY + startX;
	for (int i = 0; i < segmentWidth; ++i) {
		for (int j = 0; j < segmentWidth; ++j) {
			if ((tempPtr + j) >= ogreHeightData && (tempPtr + j) < dataEnd) {
				*(tempPtr + j) = *(sourcePtr + j);
			}
		}
		tempPtr += pageWidth;
		sourcePtr += segmentWidth;
	}
}
Example #9
0
void HeightMapUpdateTask::createHeightMapSegments()
{
	for (SegmentStore::const_iterator I = mSegments.begin(); I != mSegments.end(); ++I) {
		Mercator::Segment* segment = *I;
		if (segment) {
			IHeightMapSegment* heightMapSegment = 0;
			Mercator::Matrix<2, 2, Mercator::BasePoint>& basePoints(segment->getControlPoints());
			//If all of the base points are on the same level, and there are no mods, we know that the segment is completely flat, and we can save some memory by using a HeightMapFlatSegment instance.
			if (WFMath::Equal(basePoints[0].height(), basePoints[1].height()) && WFMath::Equal(basePoints[1].height(), basePoints[2].height()) && WFMath::Equal(basePoints[2].height(), basePoints[3].height()) && (segment->getMods().size() == 0)) {
				heightMapSegment = new HeightMapFlatSegment(basePoints[0].height());
			} else {
				HeightMapBuffer* buffer = mProvider.checkout();
				if (buffer) {
					memcpy(buffer->getBuffer()->getData(), segment->getPoints(), sizeof(float) * segment->getSize() * segment->getSize());
					heightMapSegment = new HeightMapSegment(buffer);
				}
			}
			if (heightMapSegment) {
				mHeightMapSegments.push_back(std::pair<WFMath::Point<2>, IHeightMapSegment*>(WFMath::Point<2>(segment->getXRef() / segment->getResolution(), segment->getYRef() / segment->getResolution()), heightMapSegment));
			}
		}
	}

}
Example #10
0
int main()
{
    Mercator::Terrain t;

    // Add a null test shader to the terrain
    Mercator::Shader * shader = new TestShader;
    t.addShader(shader, 0);

    // Create a test area with a shape which intersects
    // the Segment at 0,0
    Mercator::Area* a1 = new Mercator::Area(0, false);
    
    WFMath::Polygon<2> p;
    p.addCorner(p.numCorners(), WFMath::Point<2>(3, 4));
    p.addCorner(p.numCorners(), WFMath::Point<2>(10, 10));
    p.addCorner(p.numCorners(), WFMath::Point<2>(14, 6));
    p.addCorner(p.numCorners(), WFMath::Point<2>(18, 4));
    p.addCorner(p.numCorners(), WFMath::Point<2>(17, 19));
    p.addCorner(p.numCorners(), WFMath::Point<2>(6, 20));
    p.addCorner(p.numCorners(), WFMath::Point<2>(-1, 18));
    p.addCorner(p.numCorners(), WFMath::Point<2>(-8, 11));
    
    a1->setShape(p);

    // Add enough base points to force the creation of the Segment at 0,0
    t.setBasePoint(0, 0, -1);
    t.setBasePoint(0, 1, 8);
    t.setBasePoint(1, 0, 2);
    t.setBasePoint(1, 1, 11);

    // Get the Segment at 0,0
    Mercator::Segment * seg = t.getSegmentAtIndex(0,0);

    assert(seg != 0);

    // Get the surfaces, and add one corresponding to the shader we added.
    // We need to do this as the functions that would normally make it happen
    // have been stubbed out.
    Mercator::Segment::Surfacestore & sss = seg->getSurfaces();

    Mercator::Surface * sfce = new Mercator::Surface(*seg, *shader);

    // Force allocation of the surface buffer so we can check later that it
    // gets destroyed when the area is added to the terrain.
    sfce->allocate();
    assert(sfce->isValid());

    // Add the surface to the store for this segment
    sss[0] = sfce;

    // Add the area which should cause relevant surface date to be invalidated
    t.addArea(a1);

    // We assert this to ensure that the buffer has been de-allocated
    // by a call to Surface::invalidate caused by adding the Area.
    assert(!sfce->isValid());

    // force the surface to re-allocate
    sfce->allocate();
    assert(sfce->isValid());

    // Modify the areas shape
    p.addCorner(p.numCorners(), WFMath::Point<2>(-9, 12));
    a1->setShape(p);

    // and cause an area update
    t.updateArea(a1);

    // Check the surface has been invalidated again
    assert(!sfce->isValid());

    // force the surface to re-allocate
    sfce->allocate();
    assert(sfce->isValid());

    t.removeArea(a1);

    // Check the surface has been invalidated again
    assert(!sfce->isValid());
}
Example #11
0
//test intersection using a rudimentary physics simulation
//this drops a particle onto the terrain and it bounces around a bit
int main()
{
    Mercator::Terrain terrain;
    
    terrain.setBasePoint(0, 0, 2.8);
    terrain.setBasePoint(1, 0, 7.1);
    terrain.setBasePoint(0, 1, 0.2);
    terrain.setBasePoint(1, 1, 14.7);

    Mercator::Segment * segment = terrain.getSegment(0, 0);

    if (segment == 0) {
        std::cerr << "Segment not created by addition of required basepoints"
                  << std::endl << std::flush;
        return 1;
    }

    segment->populate();
    
    WFMath::Point<3> pos(30.0,30.0,100.0); //starting position
    WFMath::Vector<3> vel(0.0,1.0,0.0); //starting velocity
    WFMath::Vector<3> grav(0.0,0.0,-9.8); //gravity

    WFMath::Point<3> intersection;
    WFMath::Vector<3> intnormal;
    
    float timestep = 0.1;
    float e = 0.2; //elasticity of collision
    float totalT = 20.0; //time limit 
    float par = 0.0;
    float t = timestep;

    while (totalT > timestep) {
        vel += t * grav;
        if (Mercator::Intersect(terrain, pos, vel * t, intersection, intnormal, par)) {
            //set pos to collision time, 
            //less a small amout to keep objects apart
            pos = intersection - (vel * .01 * t); 
                                                      
            WFMath::Vector<3> impulse = intnormal * (Dot(vel, intnormal) * -2);
            std::cerr << "HIT" << std::endl;
            vel = (vel + impulse) * e; //not sure of the impulse equation, but this will do
                
            if (vel.sqrMag() < 0.01) {
                //stop if velocities are small
                std::cerr << "friction stop" << std::endl;
                break;
            }
            totalT -= par*t;
            t = (1.0-par)*t;
        }
        else {
            pos += vel*t;
            totalT -= t;
            t = timestep;
        }

        std::cerr << "timeLeft:" << totalT << " end pos" << pos << " vel" << vel << std::endl;
    }
    
   return 0;
}
Example #12
0
int main(int argc, char* argv[])
{
    Mercator::Area* a1 = new Mercator::Area(1, false);
    
    WFMath::Polygon<2> p;
    p.addCorner(p.numCorners(), Point2(3, 4));
    p.addCorner(p.numCorners(), Point2(10, 10));
    p.addCorner(p.numCorners(), Point2(-1, 18));
    p.addCorner(p.numCorners(), Point2(-8, 11));
    
    a1->setShape(p);
    
    Mercator::Terrain terrain(Mercator::Terrain::SHADED, seg_size);

    Mercator::AreaShader* ashade = new Mercator::AreaShader(1);
    terrain.addShader(ashade, 0);
    
    terrain.setBasePoint(-2, -1, 5);
    terrain.setBasePoint(-2, 0, 2);
    terrain.setBasePoint(-2, 1, 19);
    
    terrain.setBasePoint(-1, -1, 4);
    terrain.setBasePoint(-1, 0, 6);
    terrain.setBasePoint(-1, 1, 10);
    
    terrain.setBasePoint(0, -1, 2);
    terrain.setBasePoint(0, 0, -1);
    terrain.setBasePoint(0, 1, 8);
    terrain.setBasePoint(0, 2, 11);
    
    terrain.setBasePoint(1, -1, 7);
    terrain.setBasePoint(1, 0, 2);
    terrain.setBasePoint(1, 1, 11);
    terrain.setBasePoint(1, 2, 9);
    
    terrain.setBasePoint(2, -1, 3);
    terrain.setBasePoint(2, 0, 8);
    terrain.setBasePoint(2, 1, 2);

    terrain.setBasePoint(3, -1, 6);
    terrain.setBasePoint(3, 0, 7);
    terrain.setBasePoint(3, 1, 9);
    
    terrain.addArea(a1);
    
    Mercator::Segment* seg = terrain.getSegment(0,0);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));
    
    seg = terrain.getSegment(1,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);
    assert(a1->checkIntersects(*seg) == false);

    WFMath::Polygon<2> clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());
    
    seg = terrain.getSegment(-1,0);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));
    
    clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());
    
    seg = terrain.getSegment(0,1);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));
    
    clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());

    seg = terrain.getSegment(2,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);
    assert(a1->checkIntersects(*seg) == false);

    p.clear();
    p.addCorner(p.numCorners(), Point2(3 + seg_size, 4));
    p.addCorner(p.numCorners(), Point2(10 + seg_size, 10));
    p.addCorner(p.numCorners(), Point2(-1 + seg_size, 18));
    p.addCorner(p.numCorners(), Point2(-8 + seg_size, 11));
    
    a1->setShape(p);

    terrain.updateArea(a1);

    seg = terrain.getSegment(0,0);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));
    
    seg = terrain.getSegment(1,0);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));

    clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());
    
    seg = terrain.getSegment(-1,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);
    assert(a1->checkIntersects(*seg) == false);
    
    seg = terrain.getSegment(0,1);
    assert(seg->getAreas().size() == 1);
    assert(seg->getAreas().count(1) == 1);
    assert(a1->checkIntersects(*seg));
    
    clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());

    seg = terrain.getSegment(2,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);
    assert(a1->checkIntersects(*seg) == false);

    clipped = a1->clipToSegment(*seg);
    assert(clipped.isValid());

    terrain.removeArea(a1);

    seg = terrain.getSegment(0,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);

    seg = terrain.getSegment(1,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);

    seg = terrain.getSegment(-1,0);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);

    seg = terrain.getSegment(0,1);
    assert(seg->getAreas().size() == 0);
    assert(seg->getAreas().count(1) == 0);

    testAreaShader();

    testAddToSegment();
    
    return EXIT_SUCCESS;
}
int main()
{
    Mercator::Terrain terrain;
    
    terrain.setBasePoint(0, 0, 2.8);
    terrain.setBasePoint(1, 0, 7.1);
    terrain.setBasePoint(0, 1, 0.2);
    terrain.setBasePoint(1, 1, 14.7);

    Mercator::Segment * segment = terrain.getSegment(0, 0);

    if (segment == 0) {
        std::cerr << "Segment not created by addition of required basepoints"
                  << std::endl << std::flush;
        return 1;
    }

    segment->populate();
    
    //test box definitely outside terrain
    WFMath::AxisBox<3> highab(WFMath::Point<3> (10.0, 10.0, segment->getMax() + 3.0), 
                          WFMath::Point<3> (20.0, 20.0, segment->getMax() + 6.1));

    if (Mercator::Intersect(terrain, highab)) {
        std::cerr << "axisbox intersects with terrain even though it should be above it"
            << std::endl;
        return 1;
    }

    //test box definitely inside terrain
    WFMath::AxisBox<3> lowab(WFMath::Point<3> (10.0, 10.0, segment->getMin() - 6.1), 
                          WFMath::Point<3> (20.0, 20.0, segment->getMax() - 3.0));

    if (!Mercator::Intersect(terrain, lowab)) {
        std::cerr << "axisbox does not intersect with terrain even though it should be below it"
            << std::endl;
        return 1;
    }


    //test axis box moved from above terrain to below it. 
    bool inter=false;
    float dz = highab.highCorner()[2] - highab.lowCorner()[2] - 0.1;
    while (highab.highCorner()[2] > segment->getMin()) {
        highab.shift(WFMath::Vector<3>(0.0, 0.0, -dz));
        if (Mercator::Intersect(terrain, highab)) {
            inter=true;
            break;
        }
    }
    
    if (!inter) {
        std::cerr << "axisbox passed through terrain with no intersection"
            << std::endl;
        return 1;
    }
     

    //test axisbox that spans two segments
    terrain.setBasePoint(0, 2, 4.8);
    terrain.setBasePoint(1, 2, 3.7);

    Mercator::Segment *segment2 = terrain.getSegment(0, 1);
    segment2->populate();

    float segmax=std::max(segment->getMax(), segment2->getMax());
    float segmin=std::min(segment->getMin(), segment2->getMin());
    
    WFMath::AxisBox<3> ab(WFMath::Point<3> (50.0, 10.0, segmax + 3.0), 
                          WFMath::Point<3> (70.0, 20.0, segmax + 6.1));

    if (Mercator::Intersect(terrain, ab)) {
        std::cerr << "axisbox2 intersects with terrain even though it should be above it"
            << std::endl;
        return 1;
    }

    WFMath::AxisBox<3> ab2(WFMath::Point<3> (50.0, 10.0, segmin - 6.1), 
                          WFMath::Point<3> (70.0, 20.0, segmin + 3.0));

    if (!Mercator::Intersect(terrain, ab2)) {
        std::cerr << "axisbox2 does not intersect with terrain even though it should be below it"
            << std::endl;
        return 1;
    }


    WFMath::Point<3> intPoint;
    WFMath::Vector<3> intNorm;
    float par;
    //test vertical ray
    if (Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,0.0,50.0), intPoint, intNorm, par)) {
        std::cerr << "vertical ray intersected when it shouldnt" << std::endl;
        return 1;
    }
    
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "vertical ray didnt intersect when it should" << std::endl;
        return 1;
    }

    //test each quadrant
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,10.0,-100.0), intPoint, intNorm, par)) {
        std::cerr << "quad1 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,-15.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad2 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,-10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad3 ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "quad4 ray didnt intersect when it should" << std::endl;
        return 1;
    }
    
    //test dx==0 and dy==0
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "y+ ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(0.0,-10.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "y- ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(-10.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "x- ray didnt intersect when it should" << std::endl;
        return 1;
    }

    if (!Mercator::Intersect(terrain, WFMath::Point<3>(20.1, 20.2, segmax + 3), 
                               WFMath::Vector<3>(10.0,0.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "x+ ray didnt intersect when it should" << std::endl;
        return 1;
    }
    
    //test a longer ray
    if (!Mercator::Intersect(terrain, WFMath::Point<3>(-10.08, -20.37, segmax + 3), 
                               WFMath::Vector<3>(100.0,183.0,-50.0), intPoint, intNorm, par)) {
        std::cerr << "long ray didnt intersect when it should" << std::endl;
        return 1;
    }
 
    //check the height value
    float h;
    WFMath::Vector<3> n;
    terrain.getHeightAndNormal(intPoint[0], intPoint[1], h, n);
    n.normalize();

    if (n != intNorm) {
        std::cerr << "calculated normal is different from getHeightAndNormal" << std::endl;
        std::cerr << intPoint << std::endl;
        std::cerr << intNorm << "!=" << n << std::endl;
       // return 1;
    }
    
    // We can't check for equality here is it just doesn't work with
    // floats. Look it up in any programming book if you don't believe me.
    //  - 20040721 <*****@*****.**>
    if (fabs(h - intPoint[2]) > 0.00001) {
        std::cerr << "calculated height is different from getHeightAndNormal" << std::endl;
        std::cerr << h << "!=" << intPoint[2] << std::endl;
        return 1;
    }
        
    return 0;
}