Jump to content

how to Move camera to fit 3D scene??


photo

Recommended Posts

Posted

 

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

Posted

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;
}

 

Posted

 

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 .. ㅠㅠ

Posted

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?

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Posted

 

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?

 

Posted

 

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

Posted

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

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Posted

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?

Posted
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?
×
×
  • Create New...