Merge pull request #268 from eightyeight/terrain-import-flipped

Importing terrain heightmaps flips Y-axis
This commit is contained in:
SilentMike 2013-03-25 14:03:11 -07:00
commit 769268784f
8 changed files with 144 additions and 22 deletions

View file

@ -233,7 +233,8 @@ public:
F32 heightScale, F32 heightScale,
F32 metersPerPixel, F32 metersPerPixel,
const Vector<U8> &layerMap, const Vector<U8> &layerMap,
const Vector<String> &materials ); const Vector<String> &materials,
bool flipYAxis = true );
#ifdef TORQUE_TOOLS #ifdef TORQUE_TOOLS
bool exportHeightMap( const UTF8 *filePath, const String &format ) const; bool exportHeightMap( const UTF8 *filePath, const String &format ) const;

View file

@ -683,7 +683,8 @@ void TerrainFile::setHeightMap( const Vector<U16> &heightmap, bool updateCollisi
void TerrainFile::import( const GBitmap &heightMap, void TerrainFile::import( const GBitmap &heightMap,
F32 heightScale, F32 heightScale,
const Vector<U8> &layerMap, const Vector<U8> &layerMap,
const Vector<String> &materials ) const Vector<String> &materials,
bool flipYAxis )
{ {
AssertFatal( heightMap.getWidth() == heightMap.getHeight(), "TerrainFile::import - Height map is not square!" ); AssertFatal( heightMap.getWidth() == heightMap.getHeight(), "TerrainFile::import - Height map is not square!" );
AssertFatal( isPow2( heightMap.getWidth() ), "TerrainFile::import - Height map is not power of two!" ); AssertFatal( isPow2( heightMap.getWidth() ), "TerrainFile::import - Height map is not power of two!" );
@ -702,23 +703,48 @@ void TerrainFile::import( const GBitmap &heightMap,
{ {
const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale ); const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale );
const U16 *iBits = (const U16*)heightMap.getBits(); const U16 *iBits = (const U16*)heightMap.getBits();
for ( U32 i = 0; i < mSize * mSize; i++ ) if ( flipYAxis )
{ {
U16 height = convertBEndianToHost( *iBits ); for ( U32 i = 0; i < mSize * mSize; i++ )
*oBits = (U16)mCeil( (F32)height * toFixedPoint ); {
++oBits; U16 height = convertBEndianToHost( *iBits );
++iBits; *oBits = (U16)mCeil( (F32)height * toFixedPoint );
++oBits;
++iBits;
}
}
else
{
for(S32 y = mSize - 1; y >= 0; y--) {
for(U32 x = 0; x < mSize; x++) {
U16 height = convertBEndianToHost( *iBits );
mHeightMap[x + y * mSize] = (U16)mCeil( (F32)height * toFixedPoint );
++iBits;
}
}
} }
} }
else else
{ {
const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale ); const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale );
const U8 *iBits = heightMap.getBits(); const U8 *iBits = heightMap.getBits();
for ( U32 i = 0; i < mSize * mSize; i++ ) if ( flipYAxis )
{ {
*oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint ); for ( U32 i = 0; i < mSize * mSize; i++ )
++oBits; {
iBits += heightMap.getBytesPerPixel(); *oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
++oBits;
iBits += heightMap.getBytesPerPixel();
}
}
else
{
for(S32 y = mSize - 1; y >= 0; y--) {
for(U32 x = 0; x < mSize; x++) {
mHeightMap[x + y * mSize] = (U16)mCeil( ((F32)*iBits) * toFixedPoint );
iBits += heightMap.getBytesPerPixel();
}
}
} }
} }

View file

@ -152,7 +152,8 @@ public:
void import( const GBitmap &heightMap, void import( const GBitmap &heightMap,
F32 heightScale, F32 heightScale,
const Vector<U8> &layerMap, const Vector<U8> &layerMap,
const Vector<String> &materials ); const Vector<String> &materials,
bool flipYAxis = true );
/// Updates the terrain grid for the specified area. /// Updates the terrain grid for the specified area.
void updateGrid( const Point2I &minPt, const Point2I &maxPt ); void updateGrid( const Point2I &minPt, const Point2I &maxPt );

View file

@ -120,8 +120,8 @@ ConsoleStaticMethod( TerrainBlock, createNew, S32, 5, 5,
return terrain->getId(); return terrain->getId();
} }
ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7, ConsoleStaticMethod( TerrainBlock, import, S32, 7, 8,
"( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers )\n" "( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers[, bool flipYAxis=true] )\n"
"" ) "" )
{ {
// Get the parameters. // Get the parameters.
@ -131,6 +131,7 @@ ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7,
F32 heightScale = dAtof(argv[4]); F32 heightScale = dAtof(argv[4]);
const UTF8 *opacityFiles = argv[5]; const UTF8 *opacityFiles = argv[5];
const UTF8 *materialsStr = argv[6]; const UTF8 *materialsStr = argv[6];
bool flipYAxis = argc == 8? dAtob(argv[7]) : true;
// First load the height map and validate it. // First load the height map and validate it.
Resource<GBitmap> heightmap = GBitmap::load( hmap ); Resource<GBitmap> heightmap = GBitmap::load( hmap );
@ -251,12 +252,12 @@ ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7,
// Do we have an existing terrain with that name... then update it! // Do we have an existing terrain with that name... then update it!
TerrainBlock *terrain = dynamic_cast<TerrainBlock*>( Sim::findObject( terrainName ) ); TerrainBlock *terrain = dynamic_cast<TerrainBlock*>( Sim::findObject( terrainName ) );
if ( terrain ) if ( terrain )
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials ); terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis );
else else
{ {
terrain = new TerrainBlock(); terrain = new TerrainBlock();
terrain->assignName( terrainName ); terrain->assignName( terrainName );
terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials ); terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis );
terrain->registerObject(); terrain->registerObject();
// Add to mission group! // Add to mission group!
@ -272,7 +273,8 @@ bool TerrainBlock::import( const GBitmap &heightMap,
F32 heightScale, F32 heightScale,
F32 metersPerPixel, F32 metersPerPixel,
const Vector<U8> &layerMap, const Vector<U8> &layerMap,
const Vector<String> &materials ) const Vector<String> &materials,
bool flipYAxis)
{ {
AssertFatal( isServerObject(), "TerrainBlock::import - This should only be called on the server terrain!" ); AssertFatal( isServerObject(), "TerrainBlock::import - This should only be called on the server terrain!" );
@ -299,7 +301,7 @@ bool TerrainBlock::import( const GBitmap &heightMap,
} }
// The file does a bunch of the work. // The file does a bunch of the work.
mFile->import( heightMap, heightScale, layerMap, materials ); mFile->import( heightMap, heightScale, layerMap, materials, flipYAxis );
// Set the square size. // Set the square size.
mSquareSize = metersPerPixel; mSquareSize = metersPerPixel;

View file

@ -510,6 +510,26 @@
buttonType = "PushButton"; buttonType = "PushButton";
useMouseEvents = "0"; useMouseEvents = "0";
}; };
new GuiCheckBoxCtrl() {
text = " Flip Y axis?";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "12 222";
extent = "140 30";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "FlipYAxis";
canSave = "1";
canSaveDynamicFields = "0";
};
}; };
}; };
//--- OBJECT WRITE END --- //--- OBJECT WRITE END ---
@ -533,6 +553,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel = %this-->MetersPerPixel.getText(); %metersPerPixel = %this-->MetersPerPixel.getText();
%heightScale = %this-->HeightScale.getText(); %heightScale = %this-->HeightScale.getText();
%flipYAxis = %this-->FlipYAxis.isStateOn();
// Grab and validate terrain object name. // Grab and validate terrain object name.
%terrainName = %this-->TerrainName.getText(); %terrainName = %this-->TerrainName.getText();
@ -568,7 +590,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel, %metersPerPixel,
%heightScale, %heightScale,
%opacityNames, %opacityNames,
%materialNames ); %materialNames,
%flipYAxis );
Canvas.popDialog( %this ); Canvas.popDialog( %this );

View file

@ -510,6 +510,26 @@
buttonType = "PushButton"; buttonType = "PushButton";
useMouseEvents = "0"; useMouseEvents = "0";
}; };
new GuiCheckBoxCtrl() {
text = " Flip Y axis?";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "12 222";
extent = "140 30";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "FlipYAxis";
canSave = "1";
canSaveDynamicFields = "0";
};
}; };
}; };
//--- OBJECT WRITE END --- //--- OBJECT WRITE END ---
@ -533,6 +553,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel = %this-->MetersPerPixel.getText(); %metersPerPixel = %this-->MetersPerPixel.getText();
%heightScale = %this-->HeightScale.getText(); %heightScale = %this-->HeightScale.getText();
%flipYAxis = %this-->FlipYAxis.isStateOn();
// Grab and validate terrain object name. // Grab and validate terrain object name.
%terrainName = %this-->TerrainName.getText(); %terrainName = %this-->TerrainName.getText();
@ -568,7 +590,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel, %metersPerPixel,
%heightScale, %heightScale,
%opacityNames, %opacityNames,
%materialNames ); %materialNames,
%flipYAxis );
Canvas.popDialog( %this ); Canvas.popDialog( %this );

View file

@ -510,6 +510,26 @@
buttonType = "PushButton"; buttonType = "PushButton";
useMouseEvents = "0"; useMouseEvents = "0";
}; };
new GuiCheckBoxCtrl() {
text = " Flip Y axis?";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "12 222";
extent = "140 30";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "FlipYAxis";
canSave = "1";
canSaveDynamicFields = "0";
};
}; };
}; };
//--- OBJECT WRITE END --- //--- OBJECT WRITE END ---
@ -533,6 +553,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel = %this-->MetersPerPixel.getText(); %metersPerPixel = %this-->MetersPerPixel.getText();
%heightScale = %this-->HeightScale.getText(); %heightScale = %this-->HeightScale.getText();
%flipYAxis = %this-->FlipYAxis.isStateOn();
// Grab and validate terrain object name. // Grab and validate terrain object name.
%terrainName = %this-->TerrainName.getText(); %terrainName = %this-->TerrainName.getText();
@ -568,7 +590,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel, %metersPerPixel,
%heightScale, %heightScale,
%opacityNames, %opacityNames,
%materialNames ); %materialNames,
%flipYAxis );
Canvas.popDialog( %this ); Canvas.popDialog( %this );

View file

@ -510,6 +510,26 @@
buttonType = "PushButton"; buttonType = "PushButton";
useMouseEvents = "0"; useMouseEvents = "0";
}; };
new GuiCheckBoxCtrl() {
text = " Flip Y axis?";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
position = "12 222";
extent = "140 30";
minExtent = "8 2";
horizSizing = "right";
vertSizing = "bottom";
profile = "GuiCheckBoxProfile";
visible = "1";
active = "1";
tooltipProfile = "GuiToolTipProfile";
hovertime = "1000";
isContainer = "0";
internalName = "FlipYAxis";
canSave = "1";
canSaveDynamicFields = "0";
};
}; };
}; };
//--- OBJECT WRITE END --- //--- OBJECT WRITE END ---
@ -533,6 +553,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel = %this-->MetersPerPixel.getText(); %metersPerPixel = %this-->MetersPerPixel.getText();
%heightScale = %this-->HeightScale.getText(); %heightScale = %this-->HeightScale.getText();
%flipYAxis = %this-->FlipYAxis.isStateOn();
// Grab and validate terrain object name. // Grab and validate terrain object name.
%terrainName = %this-->TerrainName.getText(); %terrainName = %this-->TerrainName.getText();
@ -568,7 +590,8 @@ function TerrainImportGui::import( %this )
%metersPerPixel, %metersPerPixel,
%heightScale, %heightScale,
%opacityNames, %opacityNames,
%materialNames ); %materialNames,
%flipYAxis );
Canvas.popDialog( %this ); Canvas.popDialog( %this );