コード例 #1
0
ファイル: map_dhm_advanced.cpp プロジェクト: Grk0/MapsEvolved
PixelBuf SteepnessMap::GetRegion(
        const MapPixelCoordInt &pos, const MapPixelDeltaInt &size) const
{
    auto fixed_bounds_pb = GetRegion_BoundsHelper(*this, pos, size);
    if (fixed_bounds_pb.GetData())
        return fixed_bounds_pb;

    double mpp;
    if (!MetersPerPixel(m_orig_map, pos + size/2, &mpp)) {
        // Return zero-initialized memory block.
        return PixelBuf(size.x, size.y);
    }
    unsigned int bezier_pixels = Bezier::N_POINTS - 1;
    double inv_bezier_meters = 1 / (bezier_pixels * mpp);

    MapPixelCoordInt req_pos = pos - MapPixelDeltaInt(1, 1);
    MapPixelDeltaInt req_size = size + MapPixelDeltaInt(2, 2);
    auto orig_data = m_orig_map->GetRegion(req_pos, req_size);
    PixelBuf result(size.x, size.y);

    unsigned int *src = orig_data.GetRawData();
    unsigned int *dest = result.GetRawData();
    for (int x=0; x < size.x; x++) {
        for (int y=0; y < size.y; y++) {
            MapPixelCoordInt pos(x+1, y+1);
            MapBezierGradient grad = Fast3x3CenterGradient(src, pos, req_size);
            grad *= inv_bezier_meters;
            double grad_steepness = atan(grad.Abs());
            int color_index = static_cast<int>(grad_steepness / (M_PI / 2) * 18);
            DEST(x, y) = steepness_colors[color_index];
        }
    }
    return result;
}
コード例 #2
0
ファイル: MapTerrain.cpp プロジェクト: mark711/Cafu
void MapTerrainT::LoadHeightData(const wxString& FileName)
{
    if (FileName.EndsWith(".ter"))
    {
        // Load terrain from Terragen file.
        FILE* FilePtr=fopen(FileName.c_str(), "rb");
        if (FilePtr==NULL) throw BitmapT::LoadErrorT();

        // Read header.
        char Header[20];
        fread(Header, sizeof(char), 16, FilePtr);
        if (strncmp(Header, "TERRAGENTERRAIN ", 16)!=0) { fclose(FilePtr); throw BitmapT::LoadErrorT(); }   // Header=="TERRAGENTERRAIN "

        // Reset the return values.
        unsigned int SizeX=0;
        unsigned int SizeY=0;

        // Other values from the file.
        VectorT MetersPerPixel(30.0, 30.0, 30.0);           // The distance in meters between two neighboured pixels.

        // Read the chunks.
        while (true)
        {
            char ChunkMarker[10];
            fread(ChunkMarker, sizeof(char), 4, FilePtr);

            if (feof(FilePtr)) break;
            if (strncmp(ChunkMarker, "EOF ", 4)==0) break;

            if (strncmp(ChunkMarker, "XPTS", 4)==0)
            {
                short int XPts;
                fread(&XPts, sizeof(XPts), 1, FilePtr);     // Read two bytes.
                SizeX=XPts;                                 // Let the XPTS chunk always override previous values (it appears only after SIZE anyway).
                fread(&XPts, sizeof(XPts), 1, FilePtr);     // Overread padding bytes.
            }
            else if (strncmp(ChunkMarker, "YPTS", 4)==0)
            {
                short int YPts;
                fread(&YPts, sizeof(YPts), 1, FilePtr);     // Read two bytes.
                SizeY=YPts;                                 // Let the YPTS chunk always override previous values (it appears only after SIZE anyway).
                fread(&YPts, sizeof(YPts), 1, FilePtr);     // Overread padding bytes.
            }
            else if (strncmp(ChunkMarker, "SIZE", 4)==0)
            {
                short int Size;
                fread(&Size, sizeof(Size), 1, FilePtr);     // Read two bytes.
                SizeX=Size+1;                               // Note that the XPTS and YPTS chunks appear *after* the SIZE chunk.
                SizeY=Size+1;
                fread(&Size, sizeof(Size), 1, FilePtr);     // Overread padding bytes.
            }
            else if (strncmp(ChunkMarker, "SCAL", 4)==0)
            {
                float Scale;
                fread(&Scale, sizeof(Scale), 1, FilePtr); MetersPerPixel.x=Scale;
                fread(&Scale, sizeof(Scale), 1, FilePtr); MetersPerPixel.y=Scale;
                fread(&Scale, sizeof(Scale), 1, FilePtr); MetersPerPixel.z=Scale;
            }
            else if (strncmp(ChunkMarker, "CRAD", 4)==0)
            {
                float PlanetRadius;
                fread(&PlanetRadius, sizeof(PlanetRadius), 1, FilePtr);     // This value is ignored.
            }
            else if (strncmp(ChunkMarker, "CRVM", 4)==0)
            {
                unsigned long RenderMode;
                fread(&RenderMode, sizeof(RenderMode), 1, FilePtr);         // This value is ignored.
            }
            else if (strncmp(ChunkMarker, "ALTW", 4)==0)
            {
                short int HeightScale;
                fread(&HeightScale, sizeof(HeightScale), 1, FilePtr);
                short int BaseHeight;
                fread(&BaseHeight, sizeof(BaseHeight), 1, FilePtr);

                if (SizeX!=SizeY) throw BitmapT::LoadErrorT();

                m_Resolution=SizeX;

                m_HeightData.Clear();
                m_HeightData.PushBackEmpty(m_Resolution*m_Resolution);

                for (unsigned long y=0; y<m_Resolution; y++)
                    for (unsigned long x=0; x<m_Resolution; x++)
                    {
                        short int Elevation;
                        fread(&Elevation, sizeof(Elevation), 1, FilePtr);

                        m_HeightData[y*m_Resolution+x]=(unsigned short)(int(Elevation)+32768);
                    }

                // Break here, because we're done *and* unspecified chunks like the THMB thumbnail-chunk might follow.
                // As I don't know how to deal with such chunks (where are the specs anyway?), just stop here.
                break;
            }
            else
            {
                // Unknown chunk?
                fclose(FilePtr);
                throw BitmapT::LoadErrorT();
            }
        }

        fclose(FilePtr);
    }
    else if (FileName.EndsWith(".pgm"))
    {
        try
        {
            // Load terrain from Portable Gray-Map file (only the ASCII variant).
            TextParserT TP(FileName.c_str(), "", true, '#');

            std::string MagicNumber=TP.GetNextToken();
            bool        IsAscii    =(MagicNumber=="P2");

            // If it's not P2 and not P5, something is wrong.
            if (!IsAscii && MagicNumber!="P5") throw TextParserT::ParseError();

            unsigned int SizeX=TP.GetNextTokenAsInt();
            unsigned int SizeY=TP.GetNextTokenAsInt();
            double MaxVal     =TP.GetNextTokenAsFloat();

            if (SizeX!=SizeY) throw BitmapT::LoadErrorT();

            m_Resolution=SizeX;

            m_HeightData.Clear();
            m_HeightData.PushBackEmpty(m_Resolution*m_Resolution);

            if (IsAscii)
            {
                // It's the P2 ascii type.
                for (unsigned long y=0; y<m_Resolution; y++)
                    for (unsigned long x=0; x<m_Resolution; x++)
                        m_HeightData[(m_Resolution-y-1)*m_Resolution+x]=(unsigned short)((TP.GetNextTokenAsFloat()/MaxVal)*65535.0);
            }
            else
            {
                // It's the P5 binary type.
                FILE* FilePtr=fopen(FileName, "rb");
                if (FilePtr==NULL) throw BitmapT::LoadErrorT();

                // Assume that after the last text token (the maximum value) exactly *one* byte of white-space (e.g. '\r' or '\n') follows.
                fseek(FilePtr, TP.GetReadPosByte()+1, SEEK_SET);

                for (unsigned long y=0; y<m_Resolution; y++)
                    for (unsigned long x=0; x<m_Resolution; x++)
                    {
                        unsigned char Value;
                        fread(&Value, sizeof(Value), 1, FilePtr);   // This probably slow as hell, but alas! Who cares?

                        m_HeightData[(m_Resolution-y-1)*m_Resolution+x]=(unsigned short)((Value/MaxVal)*65535.0);
                    }

                fclose(FilePtr);
            }
        }
        catch (const TextParserT::ParseError&)
        {
            throw BitmapT::LoadErrorT();
        }
    }
    else
    {
        // Load terrain from image file.
        BitmapT HeightMap=BitmapT(FileName.c_str());

        if (HeightMap.SizeX!=HeightMap.SizeY) throw BitmapT::LoadErrorT();

        m_Resolution=HeightMap.SizeX;

        m_HeightData.Clear();
        m_HeightData.PushBackEmpty(m_Resolution*m_Resolution);

        // Note that we pick the red channel of the RBG HeightMap.Data as the relevant channel.
        // Moreover, note that the y-axis of the HeightMap.Data points down in screen-space and thus towards us in world space.
        // Our world-space y-axis points opposite (away from us), though, and therefore we access the HeightMap.Data at (i, Size-j-1).
        for (unsigned long y=0; y<m_Resolution; y++)
            for (unsigned long x=0; x<m_Resolution; x++)
                m_HeightData[y*m_Resolution+x]=(unsigned short)((double(HeightMap.Data[(m_Resolution-y-1)*m_Resolution+x] & 0xFF)/255.0)*65535);
    }

    m_NeedsUpdate=true;
}