From 6ff1db6c0c7a712a6170d894fb883d82ffe4bcd0 Mon Sep 17 00:00:00 2001 From: Daniel Buckmaster Date: Thu, 21 Mar 2013 09:22:07 +1100 Subject: [PATCH 1/2] Made the flipped y-axis on terrain import optional. Pass a final boolean argument to TerrainBlock::import to control y-axis flipping. It is enabled by default, since this was the previous default behavior. This should be added as an option in the terrain import dialog - see game/tools/worldEditor/gui/guiTerrainImportGui.gui --- Engine/source/terrain/terrData.h | 3 +- Engine/source/terrain/terrFile.cpp | 46 ++++++++++++++++++++++------ Engine/source/terrain/terrFile.h | 3 +- Engine/source/terrain/terrImport.cpp | 14 +++++---- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/Engine/source/terrain/terrData.h b/Engine/source/terrain/terrData.h index 20588ccc0..967bfa0d1 100644 --- a/Engine/source/terrain/terrData.h +++ b/Engine/source/terrain/terrData.h @@ -233,7 +233,8 @@ public: F32 heightScale, F32 metersPerPixel, const Vector &layerMap, - const Vector &materials ); + const Vector &materials, + bool flipYAxis = true ); #ifdef TORQUE_TOOLS bool exportHeightMap( const UTF8 *filePath, const String &format ) const; diff --git a/Engine/source/terrain/terrFile.cpp b/Engine/source/terrain/terrFile.cpp index ccb49f10d..5edd2e2c7 100644 --- a/Engine/source/terrain/terrFile.cpp +++ b/Engine/source/terrain/terrFile.cpp @@ -683,7 +683,8 @@ void TerrainFile::setHeightMap( const Vector &heightmap, bool updateCollisi void TerrainFile::import( const GBitmap &heightMap, F32 heightScale, const Vector &layerMap, - const Vector &materials ) + const Vector &materials, + bool flipYAxis) { 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!" ); @@ -702,23 +703,48 @@ void TerrainFile::import( const GBitmap &heightMap, { const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale ); const U16 *iBits = (const U16*)heightMap.getBits(); - for ( U32 i = 0; i < mSize * mSize; i++ ) + if ( flipYAxis ) { - U16 height = convertBEndianToHost( *iBits ); - *oBits = (U16)mCeil( (F32)height * toFixedPoint ); - ++oBits; - ++iBits; + for ( U32 i = 0; i < mSize * mSize; i++ ) + { + U16 height = convertBEndianToHost( *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 { const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale ); const U8 *iBits = heightMap.getBits(); - for ( U32 i = 0; i < mSize * mSize; i++ ) + if ( flipYAxis ) { - *oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint ); - ++oBits; - iBits += heightMap.getBytesPerPixel(); + for ( U32 i = 0; i < mSize * mSize; i++ ) + { + *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(); + } + } } } diff --git a/Engine/source/terrain/terrFile.h b/Engine/source/terrain/terrFile.h index 04bac3d9b..3640d3664 100644 --- a/Engine/source/terrain/terrFile.h +++ b/Engine/source/terrain/terrFile.h @@ -152,7 +152,8 @@ public: void import( const GBitmap &heightMap, F32 heightScale, const Vector &layerMap, - const Vector &materials ); + const Vector &materials, + bool flipYAxis = true ); /// Updates the terrain grid for the specified area. void updateGrid( const Point2I &minPt, const Point2I &maxPt ); diff --git a/Engine/source/terrain/terrImport.cpp b/Engine/source/terrain/terrImport.cpp index 28c384e5f..ede106402 100644 --- a/Engine/source/terrain/terrImport.cpp +++ b/Engine/source/terrain/terrImport.cpp @@ -120,8 +120,8 @@ ConsoleStaticMethod( TerrainBlock, createNew, S32, 5, 5, return terrain->getId(); } -ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7, - "( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers )\n" +ConsoleStaticMethod( TerrainBlock, import, S32, 7, 8, + "( String terrainName, String heightMap, F32 metersPerPixel, F32 heightScale, String materials, String opacityLayers[, bool flipYAxis=true] )\n" "" ) { // Get the parameters. @@ -131,6 +131,7 @@ ConsoleStaticMethod( TerrainBlock, import, S32, 7, 7, F32 heightScale = dAtof(argv[4]); const UTF8 *opacityFiles = argv[5]; const UTF8 *materialsStr = argv[6]; + bool flipYAxis = argc == 8? dAtob(argv[7]) : true; // First load the height map and validate it. Resource 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! TerrainBlock *terrain = dynamic_cast( Sim::findObject( terrainName ) ); if ( terrain ) - terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials ); + terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis ); else { terrain = new TerrainBlock(); terrain->assignName( terrainName ); - terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials ); + terrain->import( (*heightmap), heightScale, metersPerPixel, layerMap, materials, flipYAxis ); terrain->registerObject(); // Add to mission group! @@ -272,7 +273,8 @@ bool TerrainBlock::import( const GBitmap &heightMap, F32 heightScale, F32 metersPerPixel, const Vector &layerMap, - const Vector &materials ) + const Vector &materials, + bool flipYAxis) { 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. - mFile->import( heightMap, heightScale, layerMap, materials ); + mFile->import( heightMap, heightScale, layerMap, materials, flipYAxis ); // Set the square size. mSquareSize = metersPerPixel; From b868906ba52be1cbd6aea0a0b9fb76a5e0a1cfe4 Mon Sep 17 00:00:00 2001 From: Daniel Buckmaster Date: Sat, 23 Mar 2013 09:24:02 +1100 Subject: [PATCH 2/2] Added a checkbox to the terrain import GUI and fixed a space. --- Engine/source/terrain/terrFile.cpp | 2 +- .../worldEditor/gui/guiTerrainImportGui.gui | 25 ++++++++++++++++++- .../worldEditor/gui/guiTerrainImportGui.gui | 25 ++++++++++++++++++- .../worldEditor/gui/guiTerrainImportGui.gui | 25 ++++++++++++++++++- .../worldEditor/gui/guiTerrainImportGui.gui | 25 ++++++++++++++++++- 5 files changed, 97 insertions(+), 5 deletions(-) diff --git a/Engine/source/terrain/terrFile.cpp b/Engine/source/terrain/terrFile.cpp index 5edd2e2c7..85ae8741b 100644 --- a/Engine/source/terrain/terrFile.cpp +++ b/Engine/source/terrain/terrFile.cpp @@ -684,7 +684,7 @@ void TerrainFile::import( const GBitmap &heightMap, F32 heightScale, const Vector &layerMap, const Vector &materials, - bool flipYAxis) + bool flipYAxis ) { 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!" ); diff --git a/Templates/Empty PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/Empty PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui index e56cbab89..5d98864d5 100644 --- a/Templates/Empty PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui +++ b/Templates/Empty PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -510,6 +510,26 @@ buttonType = "PushButton"; 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 --- @@ -533,6 +553,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel = %this-->MetersPerPixel.getText(); %heightScale = %this-->HeightScale.getText(); + %flipYAxis = %this-->FlipYAxis.isStateOn(); + // Grab and validate terrain object name. %terrainName = %this-->TerrainName.getText(); @@ -568,7 +590,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel, %heightScale, %opacityNames, - %materialNames ); + %materialNames, + %flipYAxis ); Canvas.popDialog( %this ); diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui index e56cbab89..5d98864d5 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -510,6 +510,26 @@ buttonType = "PushButton"; 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 --- @@ -533,6 +553,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel = %this-->MetersPerPixel.getText(); %heightScale = %this-->HeightScale.getText(); + %flipYAxis = %this-->FlipYAxis.isStateOn(); + // Grab and validate terrain object name. %terrainName = %this-->TerrainName.getText(); @@ -568,7 +590,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel, %heightScale, %opacityNames, - %materialNames ); + %materialNames, + %flipYAxis ); Canvas.popDialog( %this ); diff --git a/Templates/Full PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/Full PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui index e56cbab89..5d98864d5 100644 --- a/Templates/Full PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui +++ b/Templates/Full PhysX/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -510,6 +510,26 @@ buttonType = "PushButton"; 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 --- @@ -533,6 +553,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel = %this-->MetersPerPixel.getText(); %heightScale = %this-->HeightScale.getText(); + %flipYAxis = %this-->FlipYAxis.isStateOn(); + // Grab and validate terrain object name. %terrainName = %this-->TerrainName.getText(); @@ -568,7 +590,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel, %heightScale, %opacityNames, - %materialNames ); + %materialNames, + %flipYAxis ); Canvas.popDialog( %this ); diff --git a/Templates/Full/game/tools/worldEditor/gui/guiTerrainImportGui.gui b/Templates/Full/game/tools/worldEditor/gui/guiTerrainImportGui.gui index e56cbab89..5d98864d5 100644 --- a/Templates/Full/game/tools/worldEditor/gui/guiTerrainImportGui.gui +++ b/Templates/Full/game/tools/worldEditor/gui/guiTerrainImportGui.gui @@ -510,6 +510,26 @@ buttonType = "PushButton"; 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 --- @@ -533,6 +553,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel = %this-->MetersPerPixel.getText(); %heightScale = %this-->HeightScale.getText(); + %flipYAxis = %this-->FlipYAxis.isStateOn(); + // Grab and validate terrain object name. %terrainName = %this-->TerrainName.getText(); @@ -568,7 +590,8 @@ function TerrainImportGui::import( %this ) %metersPerPixel, %heightScale, %opacityNames, - %materialNames ); + %materialNames, + %flipYAxis ); Canvas.popDialog( %this );