L3DT users' community
Large 3D terrain generator

How to get Average Altitude?

Correspondence concerning plugins and scripts; development, use, bugs and ideas.

How to get Average Altitude?

Postby Moulder » Tue Apr 16, 2013 1:01 am

I'm trying to write a plugin but could really use the average altitude value but can't seem to find a function to get it?
I'm talking about the one in the Histogram under Change heightfield vertical range, or if there is another way to find the water level value?

Any help would be very much appreciated.
Moulder
New member
 
Posts: 4
Joined: Mon Apr 15, 2013 11:37 pm

Re: How to get Average Altitude?

Postby Aaron » Tue Apr 16, 2013 12:38 pm

Hi Moulder,

Sorry, there's currently no nice function available to plugins for calculating the average height of heightmaps. I'll put this on the to-do list.

or if there is another way to find the water level value?


Yes. if you've only flooded your map with sea (the default option), then the water level is zero metres, by definition. Alternatively, you can get the water level directly from the water map by calling the zmap_GetPixel function (the level is stored in the WaterLevel member of the WaterMapPixel struct).

Cheerio,
Aaron.
User avatar
Aaron
Site Admin
 
Posts: 3687
Joined: Sun Nov 20, 2005 2:41 pm
Location: Melbourne, Australia

Re: How to get Average Altitude?

Postby Moulder » Tue Apr 16, 2013 2:14 pm

Thanks a lot for the quick reply, so guessing the histogram is using an internal function?
Guessing I'll have to check for a water map and if none exist generate one before being able to find the water level if I understand you right? :)
Moulder
New member
 
Posts: 4
Joined: Mon Apr 15, 2013 11:37 pm

Re: How to get Average Altitude?

Postby Moulder » Thu Apr 18, 2013 9:18 pm

Having another problem now, I'm trying to use

Code: Select all
zmap_SetPixel(zproj_GetMap("HF"),i,j,&value);


where value is a float, however any negative float seems to translate in to a 0.0 instead of a negative float, what is the natural format for this one to avoid this problem?
Getting a float however seems to work.
Moulder
New member
 
Posts: 4
Joined: Mon Apr 15, 2013 11:37 pm

Re: How to get Average Altitude?

Postby Aaron » Sun Apr 21, 2013 2:22 pm

Hi Moulder,

Moulder wrote:where value is a float, however any negative float seems to translate in to a 0.0 instead of a negative float, what is the natural format for this one to avoid this problem? Getting a float however seems to work.


Float is correct.

By what method are you getting a 0.0 value back from a negative height value? Is this a problem with zmap_GetPixel, or is there some other way you're getting height values that is returning zeros?

Best regards,
Aaron.
User avatar
Aaron
Site Admin
 
Posts: 3687
Joined: Sun Nov 20, 2005 2:41 pm
Location: Melbourne, Australia

Re: How to get Average Altitude?

Postby Moulder » Mon Apr 22, 2013 8:46 am

I'll try to explain using provide code snippets so here goes;

First I got a simple object just for handling my vectors;
Code: Select all
public:
   int mapSizeX;
   int mapSizeY;
   mapInfo(void);
   ~mapInfo(void);
   bool setMapSize();
   bool setValueAt(const char *wMap, int x, int y, float value);
   bool getValueAt(const char *wMap, int x, int y, float &Val);
   bool checkMapID(const char *wMap);


GetValue looks like
Code: Select all
bool mapInfo::getValueAt(const char *wMap, int x, int y, float &Val){

   if (!mapInfo::checkMapID(wMap))
      return false;

   Val = mapArrays[mapID].at( y * mapSizeX +x);
   return true;
}

SetValue Looks like
Code: Select all
bool mapInfo::setValueAt(const char *wMap, int x, int y, float value){
   
   if (!mapInfo::checkMapID(wMap))
      return false;

   mapArrays[mapID].at(y * mapSizeX +x) = value;

   return true;
}


This objects handles the float values just to let me work them over easier and faster then getting each pixel value every time and so on, it seem to work without any issues (is there an easy way of outputing values to the log window in L3DT so I can check?) as I do get values back as intended but for some reason I can get the map to go either positive or negative

Code: Select all
bool applyGeneration(){

   maxProgress = mapVectors.mapSizeX * mapVectors.mapSizeY;
   updateProg(true,"Applying heightmaps");
   maxProgress = mapVectors.mapSizeX * mapVectors.mapSizeY;
   for (int i = 0; i < mapVectors.mapSizeX ; i++){
      for (int j = 0; j < mapVectors.mapSizeY ; j++){
         float value2 = 0.0f;
         if (!mapVectors.getValueAt("BASE", i, j, value2)) return false;
         if (!zmap_SetPixel(zproj_GetMap("HF"),i,j,&value2)) return false;
         updateProg(1);
      }      
   }
   return true;
}


Depending on the values (seems to be which ever goes highest or lowest with positive being checked first) I either get everything from 0 and up, or 0 and down, never for ex both 1.0 and -1.0, first I thought it was reseting some offset or something but I do get the outline I'm suppost to get so it's either land that becomes 0 and sea leavels become negative, or sea becomes 0 and land becomes positive.

Had a krash on one of my harddrives a few days ago so I'm still restoring stuff but I'll see if I can't do a pure copy value, return value and see what happens, any ideas where the problem might be otherwise would be great :)
Moulder
New member
 
Posts: 4
Joined: Mon Apr 15, 2013 11:37 pm

Re: How to get Average Altitude?

Postby Aaron » Tue Apr 23, 2013 12:50 pm

Hi Moulder,

I didn't see anything obviously wrong in your code that would cause the problem you've observed. I guess the next step is to verify the values returned by 'mapVectors.getValueAt' that are passed into 'zmap_SetPixel'. In the code below I've added some logging to the loop to report these height values. I've also retrieved the handle to the heightfield once at the start of the function (using zproj_GetMap), rather than for each call to zmap_SetPixel, as this should save a few clock cycles. For completeness, I also added some map size validation, error reporting, and assorted housekeeping code.

Please note that this code may contain bugs, since I couldn't compile and test it without your mapInfo class. Please let me know if there are any insurmountable problems in compiling or running this code.

Cheerio,
Aaron.

Code: Select all
#include <zProj.h>
#include <zView.h>
#include <helper/zBackup.h>

bool applyGeneration(){

   // get the handle to the heightfield
   ZMAP pHF = zproj_GetMap("HF");
   if(!pHF) {
      zeoReportError("applyGeneration error:\r\n - cannot get heightfield!");
      return false;
   }
   if(MAP_Heightfield!=zmap_GetMapType(pHF)) {
      zeoReportError("applyGeneration error:\r\n - heightfield is not initialised!");
      return false;
   }
   if(mapVectors.mapSizeX!=zmap_GetWidth(pHF) || mapVectors.mapSizeY!=zmap_GetHeight(pHF) ) {
      zeoReportError("applyGeneration error:\r\n - map size mistmatch!");
      return false;
   }

   // store an undo point for the heightfield, in case things go awry
   if(!zbackup_BackupMaps("HF", "applyGeneration->HF", 0, "view.ShowMap \"HF\"")) {
      zeoReportError("applyGeneration warning:\r\n - backup failed!");
   }

   // lock the heightfield
   if(!zmap_SetBusyFlag(pHF, true)) {
      zeoReportError("applyGeneration error:\r\n - heightfield is busy");
      return false;
   }

   // set the report rate (every nth pixel value is reported to the log)
   long report_max = 32; // writing to log is slow, so don't write every pixel unless you really, really need to
   long report_cnt = 0; // counter

   // a string buffer for sprintf'ing to event log
   char tmp[128];

   maxProgress = mapVectors.mapSizeX * mapVectors.mapSizeY;
   updateProg(true,"Applying heightmaps");
   maxProgress = mapVectors.mapSizeX * mapVectors.mapSizeY;
   for (int i = 0; i < mapVectors.mapSizeX ; i++){
      for (int j = 0; j < mapVectors.mapSizeY ; j++){

         float value2 = 0.0f;
         if (!mapVectors.getValueAt("BASE", i, j, value2)) {
            zeoReportError("applyGeneration error:\r\n - call to mapVectors.getValueAt failed!");

            zmap_SetBusyFlag(pHF, false); // cleanup
            return false;
         }

         // output value to L3DT log
         if(++report_cnt>report_max) {
            sprintf_s(tmp, 128, "i=%d,j=%d,value2=%f", i, j, value2);
            zeoReportError(tmp);
            report_cnt = 0;
         }


         if (!zmap_SetPixel(pHF,i,j,&value2)) {
            zeoReportError("applyGeneration error:\r\n - call to zmap_SetPixel failed!");

            zmap_SetBusyFlag(pHF, false); // cleanup
            return false;
         }
         
         updateProg(1);
      }     
   }

   // mark the heightfield as changed
   zmap_SetFlag(pHF, MAPFLAG_MODIFIED, true);

   // clear the heightfield mipmaps if they exist
   if(zmap_nMipmaps(pHF)) {
      zmap_ClearMipmaps(pHF);
   }

   // unlock the heightfield
   zmap_SetBusyFlag(pHF, false);

   // redraw the heightfield in the main window
   zview_ShowMap("HF");
}
User avatar
Aaron
Site Admin
 
Posts: 3687
Joined: Sun Nov 20, 2005 2:41 pm
Location: Melbourne, Australia


Return to Plugins and scripts

Who is online

Users browsing this forum: No registered users and 1 guest

cron