How to generate minimap?

#1
Hi! Ok, let's say I have a large map, with: terrain, ocean, montains and hills and dales.
like this picture

Spoiler!  Show

I need to render it into minimap (or global map for ui), how to make this ?
in result i want to see someting like this pic

Spoiler!  Show


added later:
trying to think step by step
1. need slice map into cells (regions)
2. capture each cell(region) as top-down picture (ortho camera)
3. save each picture to file
4. joint all pictures in Gimp into global map

my's 1st Q: how to save picture from camera into picture file ?

Re: How to generate minimap?

#2
Far as i know Crytek is redoing the Minimap feature. Best to wait for that? You can always fake it in the engine ofcourse by sending map coordinates to scaleform and move the map there. Display the DSS with alpha properties within a circle / rectangle in the corner.

To capture the viewport simplely navigate upwards to desired height and use the r_getscreenshot = 2 cvar.

Re: How to generate minimap?

#3
Thx lavizh for reply, but until we waiting till crytech implement this feature, we could find own solutuon for this minimapGenerator.
I got Screenshoot writer for now from active camera
void GlobalMinimapGenerator::Generate()
{

#ifdef VISUAL_DEBUG
static IPersistantDebug* debug = gEnv->pGameFramework->GetIPersistantDebug();
debug->Begin("GlobalMinimapGenerator", true);
debug->Add2DText("GlobalMinimapGenerator::Generate()", 2.0f, ColorF(1, 1, 1), 4.0f);
#endif

ICameraManager* m_pCameraManager = gEnv->pSystem->GetIPluginManager()->QueryPlugin<IPlugin_CryDefaultEntities>()->GetICameraManager();;

//m_pCameraManager->AddCamera(m_pCameraComponent);
m_pCameraManager->SwitchCameraToActive(m_pCameraComponent);

const char* filename = "screenshoot1.jpg";

char sFileName[_MAX_PATH];
cry_sprintf(sFileName, "%s/MinimapGenerator", PathUtil::GetGameFolder().c_str());
CryCreateDirectory(sFileName);

cry_sprintf(sFileName, "%s/MinimapGenerator/%s", PathUtil::GetGameFolder().c_str(), filename);

const int iWidth = gEnv->pRenderer->GetWidth();
const int iHeight = gEnv->pRenderer->GetHeight();

uint32* m_RGB = new uint32[3 * iWidth * iHeight];
gEnv->pRenderer->ReadFrameBuffer(m_RGB, iWidth, iHeight, true, EReadTextureFormat::RGB8);
//bool bOk = gEnv->pRenderer->WriteTGA((byte*)&m_RGB[0], iWidth, iHeight, sFileName, 32, 32);
bool bOk = gEnv->pRenderer->WriteJPG((byte*)&m_RGB[0], iWidth, iHeight, sFileName, 24);
delete[] m_RGB;
To capture the viewport simplely navigate upwards to desired height and use the r_getscreenshot = 2 cvar.
hmm, but i need few screenhots, captured one by one, moreover I needed special setup for camera (2d ortho view), this allow me to joining screenshots in 2d editor seamless.
Do you know how to create orthographic camera in Cryeinge?
I think I somewhere nearly to getting ortho, but do not know exactly how
with FOV = 0 do not do the trick(
// How setup ortho Camera ?
CCamera& m_camera = CCamera(m_pCameraComponent->GetCamera());
const CCamera& systemCamera = gEnv->pSystem->GetViewCamera();

float m_nearPlane = systemCamera.GetNearPlane();
float m_farPlane = systemCamera.GetNearPlane();

//m_camera.SetFrustumVertices()
m_camera.SetFrustum(systemCamera.GetViewSurfaceX(), systemCamera.GetViewSurfaceZ(), 0.0f, m_nearPlane, m_farPlane, systemCamera.GetPixelAspectRatio());
m_camera.SetMatrix(GetWorldTransformMatrix());

gEnv->pSystem->SetViewCamera(m_camera);
// Camera

Re: How to generate minimap?

#4
Here you have two choices

Scaleform :

Load UI and map locations and images
(C++)
call scaleform events update camview each tick

or

Shaders:

In render loop...
Clear the render target view
Tell cry engine to use the shader for the next render-able object
Set up the view
position the object in the mini-map
Render the geometry
draw to screen


I don't have cry engine source code to check your arguments but i believe that is whats wrong with your code..

Re: How to generate minimap?

#5
Set up the view
I need only this, do you know how to setup otho view for camera component?
Here you have two choices
I need render world map -> few pictures -> then I use gimp to joint it into global minimap picture
and then i just render part of global minimap with helps IRenderAuxImage

Code: Select all

IRenderAuxImage::DrawImage(x, y,
screenSize.x, screenSize.y, iTextureID,
0.0f, 1.0f, 1.0f, 0.0f,
color.r, color.g, color.b, fAlpha, false);
currently my problem only with camera setup for ortho (
I need somehow to setup ortho view for camera to keep going testing my generator, with perpective's view this is problem
you may take a look my generator, it slice map into few cells with same size and trying to capture each, and save each to file
this consume few frames after I press F11 key in editor
Header

Code: Select all

#pragma once
#include <CryEntitySystem/IEntityComponent.h>
#include <CryEntitySystem/IEntity.h>

// генератор сферическогоконя
class GlobalMinimapGenerator : public IEntityComponent
{
public:

static void ReflectType(Schematyc::CTypeDesc<GlobalMinimapGenerator>& desc)
{
desc.SetGUID("{839AC596-F382-448F-B2A2-2EBCF8C1CB47}"_cry_guid);
desc.SetComponentFlags({ IEntityComponent::EFlags::ClientOnly});
desc.SetEditorCategory("Utils");
desc.SetLabel("GlobalMinimapGenerator");
desc.SetDescription("generate minimap");
desc.SetIcon("icons:General/Core.ico");

desc.AddMember(&GlobalMinimapGenerator::m_generateButton, 'btn', "Generate", "Generate", "Generate Minimap", Serialization::FunctorActionButton<std::function<void()>>());
}
public:

GlobalMinimapGenerator() = default;
virtual ~GlobalMinimapGenerator() {}

// IEntityComponent
virtual void Initialize() override;
virtual uint64 GetEventMask() const override;
virtual void ProcessEvent(const SEntityEvent& event) override;
virtual void OnShutDown() override;
// ~IEntityComponent

void Generate();
void WriteNextScreenshoot(const char* fileName, uint32 index);
void DrawCells();

Serialization::FunctorActionButton<std::function<void()>> m_generateButton;
Cry::DefaultComponents::CCameraComponent* m_pCameraComponent = nullptr;
Cry::DefaultComponents::CInputComponent* m_pInputComponent = nullptr;

float distance = 0.0f;
const float cellsResolution = 4.0f;
float cellMaxFrames = 0.0f;
float cellCurrent = 0.0f;
float waitingTime = 0.1f;
float elapsed = 0;

void SetCellPos(float cellFrame);
};
source

Code: Select all

#include "GlobalMinimapGenerator.h"

#include <CrySchematyc/Reflection/TypeDesc.h>
#include <CrySchematyc/Utils/EnumFlags.h>
#include <CrySchematyc/Env/IEnvRegistry.h>
#include <CrySchematyc/Env/IEnvRegistrar.h>
#include <CrySchematyc/Env/Elements/EnvComponent.h>
#include <CrySchematyc/Env/Elements/EnvFunction.h>
#include <CrySchematyc/Env/Elements/EnvSignal.h>
#include <CrySchematyc/ResourceTypes.h>
#include <CrySchematyc/MathTypes.h>
#include <CrySchematyc/Utils/SharedString.h>

static void RegisterGlobalMinimapGeneratorComponent(Schematyc::IEnvRegistrar& registrar)
{
Schematyc::CEnvRegistrationScope scope = registrar.Scope(IEntity::GetEntityScopeGUID());
{
Schematyc::CEnvRegistrationScope componentScope = scope.Register(SCHEMATYC_MAKE_ENV_COMPONENT(GlobalMinimapGenerator));
// Functions
{

}

}
}

CRY_STATIC_AUTO_REGISTER_FUNCTION(&RegisterGlobalMinimapGeneratorComponent)

void GlobalMinimapGenerator::Initialize()
{
m_pCameraComponent = m_pEntity->GetOrCreateComponent<Cry::DefaultComponents::CCameraComponent>();
m_pCameraComponent->SetFieldOfView(0.0_degrees);

m_pInputComponent = m_pEntity->GetOrCreateComponent<Cry::DefaultComponents::CInputComponent>();

m_generateButton = Serialization::ActionButton(std::function<void()>([this]() { Generate(); }));

m_pInputComponent->RegisterAction("minimapCapture", "generate", [this](int activationMode, float value) { if (activationMode == eIS_Pressed) Generate(); });
m_pInputComponent->BindAction("minimapCapture", "generate", eAID_KeyboardMouse, EKeyId::eKI_F11);

}

uint64 GlobalMinimapGenerator::GetEventMask() const
{
return ENTITY_EVENT_BIT(ENTITY_EVENT_TIMER) | ENTITY_EVENT_BIT(ENTITY_EVENT_UPDATE);
}

void GlobalMinimapGenerator::ProcessEvent(const SEntityEvent & event)
{
switch (event.event)
{
case ENTITY_EVENT_UPDATE:
{
SEntityUpdateContext* pCtx = (SEntityUpdateContext*)event.nParam[0];
DrawCells();
}
break;
case ENTITY_EVENT_TIMER:
{

const char* filename = "screenshoot";

if (cellMaxFrames > cellCurrent)
{
m_pCameraComponent->SetFieldOfView(0.0_degrees);
cellCurrent += 1.0;
WriteNextScreenshoot(filename, (int)cellCurrent);
SetCellPos(cellCurrent);
}
}
break;
}
}

void GlobalMinimapGenerator::OnShutDown()
{

}

void GlobalMinimapGenerator::Generate()
{
// Turn off motion blur
auto myCVar = gEnv->pConsole->GetCVar("r_MotionBlur");
myCVar->Set(0);

// Set timer, catch it in ProcessEvents
m_pEntity->SetTimer(1, 1000);

// Set first cell pos
SetCellPos(cellCurrent);

#ifdef VISUAL_DEBUG
static IPersistantDebug* debug = gEnv->pGameFramework->GetIPersistantDebug();
debug->Begin("GlobalMinimapGenerator", true);
debug->Add2DText("GlobalMinimapGenerator::Generate()", 2.0f, ColorF(1, 1, 1), 5.0f);
#endif

// reset vars
cellMaxFrames = cellsResolution * cellsResolution;
cellCurrent = 0.0f;

// activate view
ICameraManager* m_pCameraManager = gEnv->pSystem->GetIPluginManager()->QueryPlugin<IPlugin_CryDefaultEntities>()->GetICameraManager();;
m_pCameraManager->SwitchCameraToActive(m_pCameraComponent);
}

void GlobalMinimapGenerator::WriteNextScreenshoot(const char* fileName, uint32 index = 0)
{
//const char* filename = "screenshoot1.jpg";

char sFileName[_MAX_PATH];
cry_sprintf(sFileName, "%s/MinimapGenerator", PathUtil::GetGameFolder().c_str());
CryCreateDirectory(sFileName);

cry_sprintf(sFileName, "%s/MinimapGenerator/%s%s.jpg", PathUtil::GetGameFolder().c_str(), fileName, CryStringUtils::toString(index).c_str());

const int iWidth = gEnv->pRenderer->GetWidth();
const int iHeight = gEnv->pRenderer->GetHeight();

uint32* m_RGB = new uint32[3 * iWidth * iHeight];
gEnv->pRenderer->ReadFrameBuffer(m_RGB, iWidth, iHeight, true, EReadTextureFormat::RGB8);
//bool bOk = gEnv->pRenderer->WriteTGA((byte*)&m_RGB[0], iWidth, iHeight, sFileName, 32, 32);
bool bOk = gEnv->pRenderer->WriteJPG((byte*)&m_RGB[0], iWidth, iHeight, sFileName, 24);
delete[] m_RGB;
}

void GlobalMinimapGenerator::DrawCells()
{
//#ifdef VISUAL_DEBUG
// static IPersistantDebug* debug = gEnv->pGameFramework->GetIPersistantDebug();
// debug->Begin("GlobalMinimapGenerator", true);
// debug->Add2DText("GlobalMinimapGenerator::Generate()", 2.0f, ColorF(1, 1, 1), 4.0f);
//#endif

}

void GlobalMinimapGenerator::SetCellPos(float cellFrame)
{
const float cellsMax = cellsResolution * cellsResolution;

if (cellFrame > cellMaxFrames)
{
#ifdef VISUAL_DEBUG
static IPersistantDebug* debug = gEnv->pGameFramework->GetIPersistantDebug();
debug->Begin("GlobalMinimapGenerator", true);
debug->Add2DText("GlobalMinimapGenerator::Finish()", 2.0f, ColorF(1, 1, 1), 4.0f);
#endif
return;
}
// calculate new map position on base currentFrame
const float fTerrainSize = static_cast<float>(gEnv->p3DEngine->GetTerrainSize());
const float cellStep = fTerrainSize / cellsResolution;
const float cellStepHalf = cellStep * 0.5f;

int cy = (int)cellCurrent / (int)cellsResolution;
int cx = (int)std::fmod((int)cellCurrent, (int)cellsResolution);

float fcy = (cy * cellStep);
float fcx = (cx * cellStep);
distance = fTerrainSize / cellsResolution;

Vec3 pos = m_pEntity->GetPos();
pos.x = fcx;
pos.y = fcy;
pos.z = distance;
m_pEntity->SetPos(pos);

// set top - down orientation
Matrix33 m = CCamera::CreateOrientationYPR(Ang3(DEG2RAD(0), DEG2RAD(-90), DEG2RAD(0)));
Quat q = Quat(m);
m_pEntity->SetRotation(q);

m_pEntity->SetTimer(1, 1000);

}

Re: How to generate minimap?

#6
For orthographic camera projection you may need to modify the camera view matrix manually by using the GitHub source engine.
The world map you provide there looks to be hand finished, some parts like the general geometry and roads were probably traced.

For displaying the map, Scaleform is most likely the way to go unless you want to code your own UI system :P.
Uniflare
CRYENGINE Community Coordinator
Here to help the community and social channels grow and thrive.

My personal belongings;
Beginner Guides | My GitHub | Splash Plugin

Re: How to generate minimap?

#7
Thx Cry-Flare for reply!
Could you plz point to me to code (cpp files, lines) where exaclty I need set otho matrix?
I think I need made just custom camera class, and on Update-event feeds the CCamera struct with right data for ortho view, Is am right ?

And secondly, why CCamera class do not provide helpers for construct othro view only perspective helpers? Could you plz reminds to cryengeeners to add such handy functional to CCamera ? Or even just add Ortho camera component in future releases of cryengine (it's a bit funny, but even isometric template that provided by cryengine, uses perspective camera, in my opinion isometric means ortho view with some angle)
The world map you provide there looks to be hand finished, some parts like the general geometry and roads were probably traced.
Yep, after all... after I'll have whole peaces of the global map I may paint on it someting, even by hand )

Re: How to generate minimap?

#8
I'm not a rendering engineer and unfortunately can't provide precise edits necessary. Speaking to an engineer here though it may be a little more difficult as certain parts of the rendering systems might be affected.

Generally though, you will want to modify the file `Code\CryEngine\CryCommon\CryMath\Cry_Camera.h`to allow the use of Orthographic matrices. Then there may be other modifications necessary to the renderer to fix visual artifacting caused by these changes.
Uniflare
CRYENGINE Community Coordinator
Here to help the community and social channels grow and thrive.

My personal belongings;
Beginner Guides | My GitHub | Splash Plugin

Who is online

Users browsing this forum: No registered users and 1 guest

cron