Ejemplo n.º 1
0
void Tile::draw(const Mercator::Terrain & h, int x, int y)
{
    if (tex_id == -1) { return; }
    glBindTexture(GL_TEXTURE_2D, tex_id);
    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    float dw = m_pw / (2 * tileSize);
    float dh = m_ph / (2 * tileSize);
    int tile_size = tileSize + 1;
    GLfloat vertices[(tile_size * tile_size) * 3],
            texcoord[(tile_size * tile_size) * 3];
    int tindex = -1;
    int vindex = -1;
    for(int j = 0; j < tile_size; ++j) {
        for(int i = 0; i < tile_size; ++i) {
            texcoord[++tindex] = m_pw/2 + dw * (i - j);
            texcoord[++tindex] = dh * (i + j);
            vertices[++vindex] = i;
            vertices[++vindex] = j;
            vertices[++vindex] = h.get(x + i, y + j);
        }
    }
    GLuint indices[(int)tileSize * tile_size * 4];
    int iindex = -1;
    for (int i = 0; i < tile_size - 1; ++i) {
        for (int j = 0; j < tile_size; ++j) {
            indices[++iindex] = j * tile_size + i;
            indices[++iindex] = j * tile_size + i + 1;
        }
        if (++i >= tileSize) { break; }
        for (int j = tileSize; j >= 0; --j) {
            indices[++iindex] = j * tile_size + i + 1;
            indices[++iindex] = j * tile_size + i;
        }
    }
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texcoord);
    glDrawElements(GL_TRIANGLE_STRIP, ++iindex, GL_UNSIGNED_INT, indices);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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());
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}