mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 00:54:54 +00:00
Merge pull request #268 from eightyeight/terrain-import-flipped
Importing terrain heightmaps flips Y-axis
This commit is contained in:
commit
769268784f
8 changed files with 144 additions and 22 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue