Jump to content

[SOLVED] Camera View Component strange init WidgetSpriteViewport


photo

Recommended Posts

Dear Unigine support,

I'm trying to properly setup an external camera view displayed in object gui panel.
For this, I'm using Component System as bellow code shows.

## CameraViewComponent.h

class DLLEI CameraViewComponent :
	public ComponentBase
{
public:
	COMPONENT(CameraViewComponent, ComponentBase);
	COMPONENT_INIT(init);
	COMPONENT_UPDATE(update);
	COMPONENT_POST_UPDATE(render);
	COMPONENT_SHUTDOWN(shutdown);

	void init();
	void update();
	void render();
	void shutdown();

	PROP_NAME("CameraViewComponent");
	PROP_PARAM(Node, BellyCamera);

private:
	ObjectMeshStaticPtr mesh;
	TexturePtr texture;
	PlayerDummyPtr camera;
	ViewportPtr viewport;
	Math::Vec3 position;
	ObjectGuiPtr object_gui;
	GuiPtr gui;
	WidgetSpriteViewportPtr sprite_viewport;
};

## CameraViewComponent.cpp

REGISTER_COMPONENT(CameraViewComponent)

void CameraViewComponent::init()
{
	object_gui = checked_ptr_cast<ObjectGui>(node);
	if (object_gui)
	{
		gui = object_gui->getGui();
		sprite_viewport = WidgetSpriteViewport::create(gui, 512, 512);
		gui->addChild(sprite_viewport, Gui::ALIGN_EXPAND);
		//if (BellyCamera.get())
		//	sprite_viewport->setCamera(checked_ptr_cast<PlayerDummy>(BellyCamera.get())->getCamera());
	}
}

void CameraViewComponent::update()
{
	if (BellyCamera.get())
		sprite_viewport->setCamera(checked_ptr_cast<PlayerDummy>(BellyCamera.get())->getCamera());
}

void CameraViewComponent::render()
{
}

void CameraViewComponent::shutdown()
{
}

I get it working properly only when I repeat sprite_viewport->setCamera in update, whereas to me it is only init.
Then maybe there's still smthg to trigger update when sync is not automatic..

When i do only in init, I get a view and can see it is kind of viewport of the world, but it is not attached to the entity (loaded from World as from CIGI).
Is looks like smthg is not ready yet on Component::init() for a proper link.

Sub-question: if recurrent sync has to be performed, would it be on update (COMPONENT_UPDATE) or on render (COMPONENT_POST_UPDATE)?

Kind regards,
Charles

Link to comment

Hi,

Thanks already for taking care to give an update ;-)
It is not blocking, just need confirmation it is properly implemented.. doubt about it.

Kind regards,
Charles

Link to comment

Hi, Charles, 

I tried to reproduce this problem but it seems like it works just fine with sprite_viewport->setCamera in both cases (only in init() or only in update()).

// AppWorldLogic::init()

player = PlayerDummy::create();
Game::setPlayer(player);

player->setPosition(Vec3(17.0f));
player->setDirection(vec3(-1.0f), vec3(0.0f, 0.0f, 1.0f));

gui_obj = ObjectGui::create(512, 512);
auto object = ComponentSystem::get()->addComponent<CameraViewComponent>(gui_obj);
object->BellyCamera = player;

 

void CameraViewComponent::init()
{
    object_gui = checked_ptr_cast<ObjectGui>(node);
    if (object_gui)
    {
        gui = object_gui->getGui();
        sprite_viewport = WidgetSpriteViewport::create(gui, 512, 512);
        gui->addChild(sprite_viewport, Gui::ALIGN_EXPAND);
        if (BellyCamera.get())
            sprite_viewport->setCamera(checked_ptr_cast<PlayerDummy>(BellyCamera.get())->getCamera());
    }
}

void CameraViewComponent::update()
{
	// Also i have tried to setCamera here, instead of ::init(), and it seems like it works just fine in both cases
	//if (BellyCamera.get())
	//	sprite_viewport->setCamera(checked_ptr_cast<PlayerDummy>(BellyCamera.get())->getCamera());
}

 

Link to comment

Hi,

Thanks for supporting in this.

There is a difference between our both context: component is loaded by CIGI.
Would it be possible for you to test with your CIGI example?

Another difference maybe: the belly camera is defined as child of the H/C, as one camera among different predefined ones.
Attached is how ObjectGui set its CameraViewComponent's Belly Camera directly with one of the predefined cam.
Keep in mind, such entity will be loaded with CIGI..

I have the sensation that at init we get a camera, but not the right one.
For later on, the camera will be like fix in the air... but not child of the H/C.

Kind regards,
Charles

UNG-belly-cam-component.PNG

Edited by Lales.Charles
Link to comment

Hi,

I added Ctrl key to activate / deactivate the continuous setCamera.. and behavior is even more weird:

- Ctrl -> belly camera moving with the entity

- Not Ctrl -> belly camera is fixed, not moving with entity anymore.. but the stream is active

- I can switch between all cameras defined in entity -> the belly one is right attached to the entity, despite what display the ObjectGui... 

Question: do you duplicate the cam in setCamera somehow..??

Self answering:
https://developer.unigine.com/en/docs/2.11/api/library/gui/class.widgetspriteviewport?rlang=cpp#setCamera_Camera_void
Copies parameters of the given Camera instance.

So.. doesn't mean it is a child...

## CameraViewComponent.cpp

void CameraViewComponent::update()
{
	if (BellyCamera.get() && App::getKeyState(App::KEY_CTRL))
		sprite_viewport->setCamera(checked_ptr_cast<PlayerDummy>(BellyCamera.get())->getCamera());
}

Kind regards,
Charles

Edited by Lales.Charles
Link to comment
  • 1 month later...

Hi,

So, here still a question -> is there a proper way to set a camera to sprite viewport once, at init.. or we have to update continuously the parameters..?

Kind regards,
Charles

Link to comment

To work with a dashboard device, I recommend rendering a picture into a texture, which can then be used as an emission texture on the device's surface. Without ObjectGui and widgets

void init()
{
// ....
	texture = Unigine::Texture::create();
	texture->create2D(viewport_size.x, viewport_size.y, Unigine::Texture::FORMAT_RG11B10F, Texture::FILTER_LINEAR | Texture::ANISOTROPY_16 | Texture::USAGE_RENDER);

	viewport = Viewport::create();
	viewport->setSkipFlags(Viewport::SKIP_VELOCITY_BUFFER);
	viewport->setRenderMode(Unigine::Viewport::RENDER_DEPTH_GBUFFER_FINAL);
// ....
}

void postUpdate
{
// ....
	viewport->renderTexture2D(player->getCamera(), texture);
	material->setTexture(material->findTexture("emission"), texture);
// ....
}

 

Link to comment

Hi,

Thanks for suggestion, try to implement it... but panel stay still black :-o
As remind:

  • HC node
    • cockpit ObjectMeshStatic
      • MFD ObjectMeshStatic (with already a texture Albedo)
        • CamGui ObjectGui (with CameraViewComponent)

Not sure I get properly the material in fact...

void init()
{
// ....
	texture = Unigine::Texture::create();
	texture->create2D(1024, 768, Unigine::Texture::FORMAT_RG11B10F, Texture::FILTER_LINEAR | Texture::ANISOTROPY_16 | Texture::USAGE_RENDER);

	viewport = Viewport::create();
	viewport->setSkipFlags(Viewport::SKIP_VELOCITY_BUFFER);
	viewport->setRenderMode(Unigine::Viewport::RENDER_DEPTH_GBUFFER_FINAL);

	material = checked_ptr_cast<ObjectMeshStatic>(node->getParent())->getMaterial(0);
// ....
}

void postUpdate
{
// ....
	viewport->renderTexture2D(checked_ptr_cast<PlayerDummy>(AttachedCamera.get())->getCamera(), texture);
	material->setTexture(material->findTexture("emission"), texture);
// ....
}

Kind regards,
Charles

Link to comment

i checked the code, everything works fine.
maybe emission state is not enabled or smth with UV? (i checked on Plane primitive)

ViewportPtr viewport;
MaterialPtr mat;
PlayerPtr player;

int AppWorldLogic::update()
{
	if (!player)
	{
		auto nr = Plugins::IG::Manager::get()->getEntity(0)->getNodeReference();
		if (nr)
		{
			auto nrc = nr->getReference();
			if (nrc)
			{
				NodePtr nodeplane = nrc->getChild(nrc->getNumChildren() - 1);
				NodePtr nodecam = nrc->getChild(nrc->getNumChildren() - 2);
				Log::message("nodeg %s %s nodec %s %s\n", nodeplane->getName(), nodeplane->getTypeName(), nodecam->getName(), nodecam->getTypeName());
				
				ObjectPtr obeject_mesh = static_ptr_cast<Object>(nodeplane);
				player = static_ptr_cast<Player>(nodecam);

				if (player && obeject_mesh)
				{
					mat = obeject_mesh->getMaterialInherit(0);
					texture = Unigine::Texture::create();
					texture->create2D(1024, 768, Unigine::Texture::FORMAT_RG11B10F, Texture::FILTER_LINEAR | Texture::ANISOTROPY_16 | Texture::USAGE_RENDER);

					viewport = Viewport::create();
					viewport->setSkipFlags(Viewport::SKIP_VELOCITY_BUFFER);
					viewport->setRenderMode(Unigine::Viewport::RENDER_DEPTH_GBUFFER_FINAL);
					
				}
			}
		}
	}

	if (viewport && player)
	{
		player->renderVisualizer();
		viewport->renderTexture2D(player->getCamera(), texture);
		mat->setTexture(mat->findTexture("emission"), texture);
	}
	return 1;
}

 

image.pngimage.pngimage.pngimage.png

 

image.png

Link to comment

Hi,

Thanks, seems working fine!

Bellow difference between ObjectGui + WidgetSpriteViewport (left) and ObjectMeshStatic + texture (right)... entity static at start, then moving forward / bakward (via CIGI).
Would you have an idea why first solution (documentation one in fact) has such issue when entity is moving?

Kind regards,
Charles

Link to comment

Hi,

Still 2 little issues...

First, as in your screenshots, I do have attached cameras visible with white edges..
Is it normal? How can I hide them?
(Bellow screenshot is runtime, not from editor)

 UNG-external-cam-visible.PNG.88b2f5236a01c86733d5a350f96ff779.PNG

Second point, there is a weird effect on light depending on entity orientation..
Would you see the quick fix I can implement?

1785211785_ExternalCamera-shadow-effect73.png.fed59b2f4a50703bb92d70321e6bf98a.png

Thanks in advance one more time.

Kind regards,
Charles

Link to comment

remove line  

player->renderVisualizer();

for remove cameras white line.

16 hours ago, Lales.Charles said:

Bellow difference between ObjectGui + WidgetSpriteViewport (left) and ObjectMeshStatic + texture (right)... entity static at start, then moving forward / bakward (via CIGI).
Would you have an idea why first solution (documentation one in fact) has such issue when entity is moving?

the widget renders between update and post-update. all changes to the entity in the post-update will be displayed in the viewport only for the next frame. but in the main camera already on this frame. we have a very old entry about this bug, something has changed in the engine and it is up to date again. we will investigate.

15 hours ago, Lales.Charles said:

there is a weird effect on light depending on entity orientation..
Would you see the quick fix I can implement?

most likely related to the render flags in the viewport. yes! please modify 

viewport = Viewport::create();
//viewport->setSkipFlags(Viewport::SKIP_VELOCITY_BUFFER); //this is unnecessary
viewport->setRenderMode(Unigine::Viewport::RENDER_DEPTH_GBUFFER_FINAL);

 

Edited by cash-metall
remove setSkipFlags
Link to comment
  • morbid changed the title to [SOLVED] Camera View Component strange init WidgetSpriteViewport
×
×
  • Create New...