Sign in to follow this  
photo

how to Move camera to fit 3D scene??

Recommended Posts

 

I want to move an object to fill the screen.

 

Similar to Move to camera in the editor.

How should I implement it?

Please help me

001.jpg

002.jpg

003.jpg

Share this post


Link to post

Hello bboguni,

This code should help you:

#include <UnigineWorld.h>
#include <UniginePlayers.h>
#include <UnigineGame.h>
#include <UnigineApp.h>

using namespace Unigine;
using namespace Unigine::Math;
void move_node_to_camera(const NodePtr &node, const PlayerPtr &player)
{
	BoundSphere node_bound = node->getWorldBoundSphere();
	float node_radius = node_bound.getRadius() * 2.0f;
	const Vec3 &node_pos = node_bound.getCenter();

	Vec3 offset = player->getWorldPosition() - node_pos;
	offset += Vec3(player->getDirection()) * node_radius;

	if (length(offset) <= UNIGINE_EPSILON)
		return;

	node->setWorldTransform(translate(offset) * node->getWorldTransform());
}

int AppWorldLogic::update()
{
	if (App::getKeyState('f'))
	{
		NodePtr node = World::getNodeByName("material_ball");
		PlayerPtr player = Game::getPlayer();
		if (node && player)
			move_node_to_camera(node, player);
	}
	return 1;
}

 

Share this post


Link to post

 

The object position should be unchanged and move the camera.

Camera angle of view is 60 and aspect ratio ex) 1920 * 1080

We need to calculate the top 10 and bottom 10 .. ㅠㅠ

Share this post


Link to post

In that case you can write your own logic based on the code provided earlier. Have you already tried some approches? Is there any issues with them?

What is top 10 and bottom 10?

Share this post


Link to post

 

I want to move the camera so that it fits tightly on the screen.

 

 

1. Get all the object bound sizes in the world to get the center and size.

2. The camera calculates the distance from the size.

3. Move the camera targetpos to the center You have moved the camera that distance.

But depending on the size of the object it doesn't fit on the screen

source code

    float fMaxWidth, fDistance, fAngle;
    fAngle = camera->GetFOV();
    core::vector3df MaxEdge(-10000000.f, -10000000.f, -10000000.f), MinEdge(10000000.f, 10000000.f, 10000000.f);
    Unigine::Math::mat4 mat;
    camera->GetViewMatrix(mat);
    Unigine::Math::mat4 Imat;

    Imat = Math::inverse(mat);

    Unigine::Math::vec3 edges[8];
    Unigine::Math::vec3 minVec = Unigine::Math::vec3(10000000.f, 10000000.f, 10000000.f);
    Unigine::Math::vec3 maxVec = Unigine::Math::vec3(-10000000.f, -10000000.f, -10000000.f);

    Unigine::Math::vec3 result;
    Unigine::Math::vec3 uCenter;


    Unigine::Math::vec3 middle = (box.getMin() + box.getMax()) / 2;
    Unigine::Math::vec3 diag = middle - box.getMax();

    edges[0].set(middle.x + diag.x, middle.y + diag.y, middle.z + diag.z);
    edges[1].set(middle.x + diag.x, middle.y - diag.y, middle.z + diag.z);
    edges[2].set(middle.x + diag.x, middle.y + diag.y, middle.z - diag.z);
    edges[3].set(middle.x + diag.x, middle.y - diag.y, middle.z - diag.z);
    edges[4].set(middle.x - diag.x, middle.y + diag.y, middle.z + diag.z);
    edges[5].set(middle.x - diag.x, middle.y - diag.y, middle.z + diag.z);
    edges[6].set(middle.x - diag.x, middle.y + diag.y, middle.z - diag.z);
    edges[7].set(middle.x - diag.x, middle.y - diag.y, middle.z - diag.z);


    for (int a = 0; a< 8; a++)
    {
        edges[a] =    mat * edges[a];
        if (maxVec.x < edges[a].x) maxVec.x = edges[a].x;
        if (maxVec.y < edges[a].y) maxVec.y = edges[a].y;
        if (maxVec.z < edges[a].z) maxVec.z = edges[a].z;

        if (minVec.x > edges[a].x) minVec.x = edges[a].x;
        if (minVec.y > edges[a].y) minVec.y = edges[a].y;
        if (minVec.z > edges[a].z) minVec.z = edges[a].z;
    }


    float fX = fabs(maxVec.x - minVec.x);
    float fY = fabs(maxVec.y - minVec.y);

    uCenter = Imat * ((minVec + maxVec) / 2) ;

    int nScreenWidth = Unigine::App::get()->getWidth();
    int nScreeHeight = Unigine::App::get()->getHeight();

    core::dimension2d<int> ardim =
        core::dimension2d<int>(nScreenWidth, nScreeHeight);

    float fRate = (float)ardim.Width / (float)ardim.Height;
    if (fX / fRate> fY)
        fMaxWidth = fX / fRate;
    else
        fMaxWidth = fY;

    fDistance = fMaxWidth / (tan(fAngle*core::GRAD_PI2 / 2.f) * 2);

    Math::vec3 Vector = camera->GetTargetVector();
    core::vector3df MovePos(uCenter.x - Vector.x*fDistance, uCenter.y - Vector.y*fDistance, uCenter.z - Vector.z*fDistance);
    camera->SetNodePosition(Math::vec3(MovePos.X * fRateU, MovePos.Y* fRateU, MovePos.Z* fRateU));
    camera->SetuTargetPos(Math::vec3(uCenter.x *fRateU, uCenter.y*fRateU, uCenter.z*fRateU));

 

 

Which part is wrong?

 

Share this post


Link to post

Could you please also send us your test content? At least a single FBX that you are using for tests?

Thanks!

Share this post


Link to post

 

We currently do not use FBX files to generate meshes dynamically.

Zoomfit distance is not correct depending on the total bound size.

 

example

3.thumb.jpg.ceb3712b17fc38ba0e5dec1e0fb6694d.jpg2.thumb.jpg.c21602a890c2186d9bd456134d39c67c.jpg1.thumb.jpg.d66a0029374a66e70ce3225a930e0998.jpg

Share this post


Link to post

In attachment you can find sample project that can be build with the latest 2.10.x SDK. All you need to do is:

  1. Create a new project called object_focus in SDK Browser (C++ API);
  2. Replace data and source directories in the newly created project with files from the attached archive;
  3. Open Visual Studio and rebuild the source/object_focus.vcxproj.

To focus you need to press F in the running application:
image.png

Thanks!

object_focus.zip

Share this post


Link to post

Thank you for your reply.

I am currently using the Engineering 2.7 SDK so I can't build object_focus.

sad....

 

Is the added source only possible when it is Orthographic?

Or is this also possible in the perspective view?

Share this post


Link to post

You can check the source code (in AppWorldLogic) and implement the same functionality with 2.7.3 as well. The screenshot above is made with perspective camera, not ortho.

Share this post


Link to post
Thank you for answer.
The top view is implemented when the camera looks at the bottom with reference to soruce.

But there is an additional problem. 
Zoom fit doesn't work with current camera position and angle, not top view ... 
is there any solution?

Share this post


Link to post
Sign in to follow this