Jump to content

how to Move camera to fit 3D scene??


photo

Recommended Posts

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

 

Link to comment

 

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

Link to comment

 

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?

 

Link to comment

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:

Link to comment

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?

Link to comment
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?
Link to comment
×
×
  • Create New...