Page MenuHomeWildfire Games

Native camera object
Needs ReviewPublic

Authored by edoput on May 21 2022, 12:26 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

This patch improves the current state of manipulating the camera from JS.

As of now the camera can be manipulated using calls such as Engine.SetCameraData, this patch improves the current states as follows.

  1. JS can now manipulate camera rotation, camera zoom and pivot position
  2. JS can now manipulate camera properties through getters and setters on the camera object

This patch is presented to stir a conversation. It is enough for my needs to set a default rotation in game
but it presents some questions.

The game does not currently have a native camera object, would this be used elsewhere? Can camera jumps
be implemented as Engine.setCamera(c) where c is a native camera object?

This patch also improves the current developer experience. JS developers come from the web background
and expect some form of objects to be available and their runtime representation be connected to the native
counterpart. Is this something we want also for the engine?

Test Plan
  1. Gather pyrogenesis developers feedback.
  2. Gather mods developers feedback.
  3. Gather newcomers mode developers feedback.

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

edoput requested review of this revision.May 21 2022, 12:26 PM
edoput created this revision.

I haven't been able to wrap my head around the pyrogenesis Script interfaces but I found some for Spidermonkey development that were enough to write this patch. I'm sorry that it doesn't fit at all with the rest of the engine but hey it works :)

Is this something we want also for the engine? Well maybe for campaigns and cinematics but we have smth similar in Atlas.

Just for reference. This is the only use of GetCameraPivot I was able to find the public mod.

This patch would change the code to something closer to

function jumpCamera(index)
{
	let position = g_JumpCameraPositions[index];
	if (!position)
		return;

	let threshold = Engine.ConfigDB_GetValue("user", "gui.session.camerajump.threshold");
	let camera Engine.getCamera();
	if (g_JumpCameraLast &&
	    Math.abs(camera.pivot.x - position.x) < threshold &&
	    Math.abs(camera.pivot.z - position.z) < threshold)
	{
                camera.moveTo([g_JumpCameraLast.x, g_JumpCameraLast.z]);
	}
	else
	{
		g_JumpCameraLast = camera.pivot;
                camera.moveTo([position.x, position.z]);
                // alternatively one can implement more getter/setter to make this work
                // camera.pivot.x = position.x
                // camera.pivot.z = position.z
	}
}

There is some related code in D3507.

I haven't been able to wrap my head around the pyrogenesis Script interfaces but I found some for Spidermonkey development that were enough to write this patch. I'm sorry that it doesn't fit at all with the rest of the engine but hey it works :)

I think your main problem has been that we don't generally create the wrapper objects in the engine. We either just have straight functions, which are fairly straightforward, or Proxy objects, which are less straightforward.

This patch also improves the current developer experience. JS developers come from the web background and expect some form of objects to be available and their runtime representation be connected to the native counterpart. Is this something we want also for the engine?

So to answer that ^: Not really that common right now.

Having a camera object might be useful if having some permanent state is relevant, or if getter properties are regularly accessed, which is maybe the case. But if so, I think it would be better to implement it as a proxy object, like the GUI objects.


On the patch itself: 'phi' and 'psi' are not really obvious names, and in general we probably want 'position' / 'rotation' & just some 'positionAt', 'lookAt' functions.

Thank you all for the feedback and the time.

Do you have an example for a proxy object that I can take a look at?

I saw the GetCameraRotation, SetCameraRotation pair is already available in another differential and I am happy to submit that instead of this.

Should I open another differential with only that changes?

Stan added a subscriber: Stan.May 25 2022, 9:53 AM
This comment was removed by Stan.

Should I open another differential with only that changes?

I think the simplest would be to create a diff for solely the functions, so that we can merge those. That should be easy.

Then you can expand this diff, but at least your mod is supported by native 0 A.D.

Do you have an example for a proxy object that I can take a look at?

So, the example in the current code is at source/gui/scripting/JSInterface_GUIProxy.h, and also the _impl.h & .cpp files. They are complex, not gonna lie. Depending on your familiarity with C++, you might try to read through them and understand what's happening.
For the case of a Camera object, you would mostly just need a subclass from js::BaseProxyHandler and to override get/set appropriately.