Heightmap importing in Atlas
This was SVN commit r12308.
This commit is contained in:
parent
e488eb4d6f
commit
c9abf6f68c
@ -309,6 +309,7 @@ enum
|
||||
ID_Open,
|
||||
ID_Save,
|
||||
ID_SaveAs,
|
||||
ID_ImportHeightmap,
|
||||
|
||||
ID_Wireframe,
|
||||
ID_MessageTrace,
|
||||
@ -332,6 +333,7 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
|
||||
EVT_MENU(ID_Open, ScenarioEditor::OnOpen)
|
||||
EVT_MENU(ID_Save, ScenarioEditor::OnSave)
|
||||
EVT_MENU(ID_SaveAs, ScenarioEditor::OnSaveAs)
|
||||
EVT_MENU(ID_ImportHeightmap, ScenarioEditor::OnImportHeightmap)
|
||||
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, ScenarioEditor::OnMRUFile)
|
||||
|
||||
EVT_MENU(ID_Quit, ScenarioEditor::OnQuit)
|
||||
@ -418,6 +420,8 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac
|
||||
menuFile->Append(ID_Save, _("&Save"));
|
||||
menuFile->Append(ID_SaveAs, _("Save &As..."));
|
||||
menuFile->AppendSeparator();//-----------
|
||||
menuFile->Append(ID_ImportHeightmap, _("&Import Heightmap..."));
|
||||
menuFile->AppendSeparator();//-----------
|
||||
menuFile->Append(ID_Quit, _("E&xit"));
|
||||
m_FileHistory.UseMenu(menuFile);//-------
|
||||
m_FileHistory.AddFilesToMenu();
|
||||
@ -713,6 +717,28 @@ void ScenarioEditor::OnOpen(wxCommandEvent& WXUNUSED(event))
|
||||
// TODO: Make this a non-undoable command
|
||||
}
|
||||
|
||||
void ScenarioEditor::OnImportHeightmap(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog dlg (NULL, wxFileSelectorPromptStr,
|
||||
_T(""), _T(""),
|
||||
_T("Valid Image files|*.png;*.jpg;*.bmp|All files (*.*)|*.*"),
|
||||
wxFD_OPEN);
|
||||
// Set default filter
|
||||
dlg.SetFilterIndex(0);
|
||||
|
||||
wxString cwd = wxFileName::GetCwd();
|
||||
|
||||
if (dlg.ShowModal() != wxID_OK)
|
||||
return;
|
||||
|
||||
OpenFile(_T("_default"), _T(""));
|
||||
|
||||
std::wstring image(dlg.GetPath().wc_str());
|
||||
POST_MESSAGE(ImportHeightmap, (image));
|
||||
|
||||
// TODO: Make this a non-undoable command
|
||||
}
|
||||
|
||||
void ScenarioEditor::OnMRUFile(wxCommandEvent& event)
|
||||
{
|
||||
wxString filename(m_FileHistory.GetHistoryFile(event.GetId() - wxID_FILE1));
|
||||
|
@ -42,6 +42,7 @@ public:
|
||||
void OnOpen(wxCommandEvent& event);
|
||||
void OnSave(wxCommandEvent& event);
|
||||
void OnSaveAs(wxCommandEvent& event);
|
||||
void OnImportHeightmap(wxCommandEvent& event);
|
||||
void OnMRUFile(wxCommandEvent& event);
|
||||
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
|
@ -28,6 +28,12 @@
|
||||
#include "graphics/Terrain.h"
|
||||
#include "graphics/TerrainTextureEntry.h"
|
||||
#include "graphics/TerrainTextureManager.h"
|
||||
#include "lib/bits.h"
|
||||
#include "lib/file/file.h"
|
||||
#include "lib/tex/tex.h"
|
||||
#include "maths/MathUtil.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Filesystem.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Loader.h"
|
||||
#include "ps/World.h"
|
||||
@ -135,6 +141,88 @@ MESSAGEHANDLER(LoadMap)
|
||||
StartGame(attrs);
|
||||
}
|
||||
|
||||
MESSAGEHANDLER(ImportHeightmap)
|
||||
{
|
||||
CStrW src = *msg->filename;
|
||||
|
||||
size_t fileSize;
|
||||
shared_ptr<u8> fileData;
|
||||
|
||||
// read in image file
|
||||
File file;
|
||||
if (file.Open(src, O_RDONLY) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to load heightmap.");
|
||||
return;
|
||||
}
|
||||
|
||||
fileSize = lseek(file.Descriptor(), 0, SEEK_END);
|
||||
lseek(file.Descriptor(), 0, SEEK_SET);
|
||||
|
||||
fileData = shared_ptr<u8>(new u8[fileSize]);
|
||||
|
||||
if (read(file.Descriptor(), fileData.get(), fileSize) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to read heightmap image.");
|
||||
file.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
file.Close();
|
||||
|
||||
// decode to a raw pixel format
|
||||
Tex tex;
|
||||
if (tex_decode(fileData, fileSize, &tex) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to decode heightmap.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert to uncompressed BGRA with no mipmaps
|
||||
if (tex_transform_to(&tex, (tex.flags | TEX_BGR | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS)) < 0)
|
||||
{
|
||||
LOGERROR(L"Failed to transform heightmap.");
|
||||
tex_free(&tex);
|
||||
return;
|
||||
}
|
||||
|
||||
// pick smallest side of texture; truncate if not divisible by PATCH_SIZE
|
||||
ssize_t terrainSize = std::min(tex.w, tex.h);
|
||||
terrainSize -= terrainSize % PATCH_SIZE;
|
||||
|
||||
// resize terrain to heightmap size
|
||||
CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
|
||||
terrain->Resize(terrainSize / PATCH_SIZE);
|
||||
|
||||
// copy heightmap data into map
|
||||
u16* heightmap = g_Game->GetWorld()->GetTerrain()->GetHeightMap();
|
||||
ssize_t hmSize = g_Game->GetWorld()->GetTerrain()->GetVerticesPerSide();
|
||||
|
||||
u8* mapdata = tex_get_data(&tex);
|
||||
ssize_t bytesPP = tex.bpp / 8;
|
||||
ssize_t mapLineSkip = tex.w * bytesPP;
|
||||
|
||||
for (ssize_t y = 0; y < terrainSize; ++y)
|
||||
{
|
||||
for (ssize_t x = 0; x < terrainSize; ++x)
|
||||
{
|
||||
int offset = y * mapLineSkip + x * bytesPP;
|
||||
|
||||
// pick colour channel with highest value
|
||||
u16 value = std::max(mapdata[offset+bytesPP*2], std::max(mapdata[offset], mapdata[offset+bytesPP]));
|
||||
|
||||
heightmap[(terrainSize-y-1) * hmSize + x] = clamp(value * 256, 0, 65535);
|
||||
}
|
||||
}
|
||||
|
||||
tex_free(&tex);
|
||||
|
||||
// update simulation
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
|
||||
if (cmpTerrain) cmpTerrain->ReloadTerrain();
|
||||
g_Game->GetView()->GetLOSTexture().MakeDirty();
|
||||
}
|
||||
|
||||
MESSAGEHANDLER(SaveMap)
|
||||
{
|
||||
CMapWriter writer;
|
||||
|
@ -146,6 +146,10 @@ QUERY(GenerateMap,
|
||||
((int, status))
|
||||
);
|
||||
|
||||
MESSAGE(ImportHeightmap,
|
||||
((std::wstring, filename))
|
||||
);
|
||||
|
||||
MESSAGE(LoadMap,
|
||||
((std::wstring, filename))
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user