Jump to content

Moving a node containing a dummyplayer and a camera


photo

Recommended Posts

Hi there

 

I'm playing around with the new Viewport and Camera classes. I have the situation, that I have an anchor NodeDummy which contains a PlayerDummy and some other nodes. In the older version I could move the anchor NodeDummy and the attached camera and nodes were following.

 

Now I'm attaching a Camera to the PlayerDummy, on which I'd like to change the viewport. This all works quite as expected, but as soon as I start moving the anchor point, my Camera remains at its starting position.

 

I would expect that I could define the modelview once for the camera and adjusting the viewport as I'd like to.

AppWorldLogic::init() {
    camPtr->setModelview(Unigine::Math::Mat4(Unigine::Math::lookAt(
    UNIGINE_VEC3(0.f, 0.f, 3.f), Unigine::Math::Vec3(0.0f, 1.0f, 3.0f), Unigine::Math::vec3(0.0f, 0.0f, 1.0f))));
    myPlayerDummy->setCamera(camPtr);
}
AppWorldLogic::update() {
    Unigine::Math::dmat4 t;
    t *= Unigine::Math::translate(Unigine::Math::dvec3(0, delta, 0));    // move the anchor about delta distance
    anchorNode->setWorldTransform(t);
}
AppWorldLogic::render() {
    Unigine::Game *game = Unigine::Game::get();    // just a dummy calculation for different frustum values
    float time = game->getTime();     
    float x = sinf(time * .25f) * .5f;
    float z = 2.0f + sinf(time * 1.0f) * 1.0f;

    camPtr->setProjection(Unigine::Math::frustum(-1.f + x, 1.f + x, -1.f, 1.f, z, 2000.f));
    vpPtr->render(camPtr);
}
      

Kind regards,

Renato

Link to comment

Hi,

 

I'm getting the expected outcome by passing the matrix to the world transform of the anchor node and to the modelview of the camera. But I'm not sure if this is performance wise a good approach...

Link to comment

Hi there,

 

Is it intended to move a camera and attached nodes by passing the matrix data to both independently? Or is there an approach to connect the camera and move only its anchor node?

 

Kind regards,

Renato

Link to comment

Hi Andrey

 

Sorry for the incomplete description.

Unigine::ViewportPtr vpPtr = Unigine::Viewport::create();

... and delta is just an floating value increased in every update call

int AppWorldLogic::update() {
	// small movement calculation
	static float delta = 0.f;
	delta += 0.3;
	if (delta > 1000.f) delta = 0.f;

	Unigine::Math::dmat4 t;
        t *= Unigine::Math::translate(Unigine::Math::dvec3(0, delta, 0)); // move the anchor about delta distance
        anchorNode->setWorldTransform(t);

return 1;

Kind regards,

Renato

Link to comment

Hi Renato,

 

Maybe I did something wrong, but I have camera that moves correctly.

 

Please, create new project via SDK Browser (call it camera_test) and replace source and data folders contents with attached. Build and run project to see a results. If there are some mistakes in my code, could you please modify project to get a described behavior.

Thanks!

 

camera_test.zip

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

Link to comment

Good morning Andrey

 

Thanks for your sample. The node is moved with the player, but the viewport changes from the render() method are not applied.

 

I changed the example and added the following code to the AppWorldLogic::update method:

//----------------------------------------------------------------
//----- Additional code for changing the frustum
Unigine::Math::dvec3 n = root_node->getNodePosition();
camPtr->setModelview(Unigine::Math::Mat4(Unigine::Math::lookAt(
	Unigine::Math::Vec3(n.x, n.y, n.z + 1), 
	Unigine::Math::Vec3(n.x, n.y + 1, n.z + 1), 
	Unigine::Math::vec3(0.0f, 0.0f, 1.0f))));
myPlayerDummy->setCamera(camPtr);
game->setPlayer(myPlayerDummy->getPlayer());
//----------------------------------------------------------------

Now, the viewport is changes, but as you see the transformation matrix is passed to the root_node as well as to the camera.

 

The attachement contains the adapted code from your test sample "camera_test". Just copy-paste it back into your project.

 

Kind regards,

Renato

camera_test.zip

Link to comment

Hi Andrey

 

I found out that rotating the anchor does also not affect the camera, just the model...

 

Kind regards,

Renato

Link to comment
  • 2 weeks later...

Hi Renato,

 

I'm afraid this is not a bug.

You can't access reference to the camera instance used by a player, you can only get a copy of it.

Therefore, for example when you need to modify projection matrix, you should write:

Unigine::CamperaPtr camera = player->getCamera();
camera->setProjection(projection); // has no effect on a camera used by the player
player->setCamera(camera);

So in your sample camPtr is actually redundant and whenever you need camera, you should read it directly from the player.

 

I agree that this is very non-obvious.

We'll think how to improve this part of API to make it less confusing.

Link to comment

Hi Ded

 

Thanks for the answer, but I'm not sure how to get the necessary feature with that... I changed my example project, to pass a new projection matrix (which I get from the frustum() method) to the copy of the player's camera. I tried this in the world logic update and in the render method, both without any effect on the viewport.

// just a dummy calculation for different frustum values
float time = game->getTime();
float xQ = sinf(time * .25f) * 0.5f;

// I tried to add these lines to the update and the render method with no result...
Unigine::CameraPtr camera = myPlayerDummy->getCamera();
camera->setProjection(Unigine::Math::frustum(-1.f + xQ, 1.f + xQ, -1.f, 1.f, 2.f, 2000.f));
myPlayerDummy->setCamera(camera);

I my previous demo project, the viewport moved due to the changes in the projection matrix, but only the position changed, it refused any rotational movements.

t_root_cam.setTranslate(Math::dvec3(0.0, delta, 1.0));
root_node->setNodeWorldPosition(t_root_cam.getTranslate());     // move the anchor about delta distance
root_node->setNodeWorldRotation(Math::quat(0.f, x, 0.f));    // rotate the anchor

We need the possibility to change the viewport/frustum on the fly, while remaining able to move the camera's root node and all its siblings with 6DOF.

 

Kind regards,

Renato

Link to comment

Hi Renato,

 

I've done some digging and have discovered more problems with cameras ownership semantics.

I've said earlier that API let's you work only with copies of cameras and that's true for UnigineScript, but for C++ is not entirely.

Player::setCamera(CameraPtr) indeed copies provided parameter to the player internal camera instance.

But Player::getCamera() returns not a copy, but reference to that internal instance.

So this code snippet should work as expected:

CameraPtr camera = player->getCamera(); // a reference to the player camera instance
camera->setProjection(...);

Sorry I misinformed you about that earlier.

 

Anyway, why this isn't working?

CameraPtr camera = player->getCamera();
camera->setProjection(...);
player->setCamera(camera);

Turns out there is a bug, that manifests itself when you're trying to copy camera to itself, due to which original camera projection matrix is lost.

So my earlier advice is wrong and without the last line this snippet should work.

 

Aforementioned bug is already fixed, about API improvements we're still not decided yet.

 

As I understand you want additional viewport to use the same modelview matrix as the main viewport, but with different projection matrix.

I've modified your sample accordingly, please check it.

And sorry, I didn't get the issue with rotation, perhaps you can provide more details?

 

camera_test.zip

Link to comment

Hi Ded

 

thanks a lot for the code snippets! I checked your example and a few questions remains... =)

 

In the render method, you advice to get a copy of the camera instance, but with this the frustum which gets set in the line below doesn't affect the camera. So it would be obvious to me to not get a copy but the reference, since we want to change its frustum, right? When I changing this line of code to get the reference of the camera the translation and the rotation of the root node works as expected.

int AppWorldLogic::render() {
   Unigine::CameraPtr camPtr= myPlayerDummy->getCamera();
   // ...
}

About the rotation: I had the observation, that the rotation of the root node didn't affect the other attached objects. But now it rotates as expected.

 

The code I was using for the dummy rotation of the camera:

int AppWorldLogic::update() {
   // ...
   game_time = game->getTime();
   float x = sinf(game_time * .4f) * 15.f;
   root_node->setNodeWorldRotation(Math::quat(0.f, x, 0.f)); 
}

Can you already make an estimation, how you are going to change the API? Do keep the interface of the camera/render/viewport classes consistent?

 

Kind regards,

Renato 

Link to comment
×
×
  • Create New...