MovingBlocks / Terasology

Terasology - open source voxel world
http://terasology.org
Apache License 2.0
3.68k stars 1.34k forks source link

Refactor Camera to be Component based #2797

Open Cervator opened 7 years ago

Cervator commented 7 years ago

One of our GSOC items and a long standing desired feature. Rather than having a hard coded camera attached to the player let any arbitrary entity hold a CameraComponent so a camera viewpoint can be sourced from it (imagine a security camera and a monitor block that can show the view from said security camera)

May have API impact but @emanuele3d would be the expert there :-)

Maybe related: #1272, #1126, http://forum.terasology.org/threads/associating-renderableworlds-to-cameras.1221, http://forum.terasology.org/threads/cinematic-module.1112, http://forum.terasology.org/threads/skysphere.1004

zeokav commented 7 years ago

Hi @Cervator ! The idea of having a separate camera component seems interesting. (Didn't know there was just one fixed camera :o) I'm going to try my hand at GSoC this time, and would like to work on something that visibly affects the game. Is there somewhere I can start looking to have a better understanding of the code-base and help with this already? Starting slightly early will help me write a better application, I hope.

skaldarnar commented 7 years ago

While trying out my new GPU w/ recording the last day I noticed that the player's hand/held item is out of sync when using a smooth camera mode and high speed multiplier. Maybe you can look into that to get your hands on the rendering/camera topics.

Cervator commented 7 years ago

@zeokav very cool to hear about GSOC potential! Yes getting an early start is great and a huge advantage as selection is likely to be competitive.

Other than the few links I added in I'm unsure about deeper technical details. I know @emanuele3d would know some stuff, as likely would @immortius and certainly @begla if he were to coincidentally fly by one of these days :-)

emanuele3d commented 7 years ago

@zeokav: I confirm I'd be available for some support/mentoring for this project.

On top of what Cervator already said I'd like to give you a glimpse of the goal.

Generally speaking in an architecture based on an Entity System (ES) components are pretty dumb and it is systems where all the magic happens: systems get the data from components and if necessary update the data on those components.

Right now cameras are pretty "clever" in the sense that they contain a lot of code in them. The goal is to have a camera component that only contains the data describing the characteristics proper of a camera. For example, if you think about a physical camera, its position and orientation are not characteristics proper of a camera. They are attributes of pretty much any existing object which is why Terasology already have position and orientation components that can be associated with any object. On the other hand, focal length and, given we are in an opengl world, near/far distances are characteristics of a camera. As is interpupillary distance if we are dealing with a VR camera.

A camera in terasology would therefore become an entity in which (at least) three components are present: a location component, an orientation component and a camera component. Systems would have to use all three components, for example, to generate modelview and projection matrices to render from that camera.

Note: those matrices -might- be cached in the camera component or perhaps in an additional CameraMatrices component specific for that purpose. But it wouldn't be the components that have the code to keep them up to date, it would be, say, a node in the renderer that takes care of that.

Perhaps all this was already clear to you but I thought I'd make it all more explicit.

zeokav commented 7 years ago

@emanuele3d Alright, thanks! I had read up on the Entity-Component system before but I absolutely had no idea about how the cameras worked. Okay then, I'll go through the camera code and see what I can gather. In case I need some things cleared, I'll contact you. :)

zeokav commented 7 years ago

Hi @emanuele3d ! I went through the code a bit more to understand more about how the entity-component-system is set up (Not only for the Camera, but everything else as well), and I was trying to keep things analogous to the input system, because that's something I've already worked with. However, I don't know if this is right : the player is the entity, and the input system is both the component and the system?

About the camera - What's happening right now is that there's a playerCamera being assigned in the WorldRendererImpl class, which is being assigned to a local player system (which further takes inputs from the InputSystem, network info from the NetworkSystem and so on). But this playerCamera cannot be currently attached to any other entity at run time since it's hardcoded when WorldRendererImpl is instantiated. So, we would like this to be a component that can be attached at run time to any entity - say any block. What I need to know is -

PS : I apologize in advance for some questions that might appear noob-ish. 😛

emanuele3d commented 7 years ago

Hi @zeokav. Some logistics first: I'm in the GMT+1 timezone. So, if I do not reply as quickly as we'd both like that might be the reason. And no worries about newbie questions: we were all newbies at some points and on many accounts I still am. :stuck_out_tongue:

Regarding the InputSystem: unfortunately I'm not familiar with it. I doubt it is both a component and a system. Why did you come to that conclusion? Certainly the input system, perhaps indirectly, affects some of the components of the Player entity, i.e. changing the data in its location and orientation components to make the player move. I believe @Cervator should be able to shed some light on this matter.

Regarding the Camera. Your understanding is correct: cameras are currently very hardcoded and yes, we'd like a component that we can attach to any entity. Regarding your bullet points:

  1. Indeed multiple cameras is one of the scenarios we envision as we switch to camera components. For example there will always be a player camera but we might also implement security cameras one can see through monitor blocks. Another scenario are portals: on one side of the portal you'd see the world your character is in, on the other side we need a matching camera that allows us to render what's visible through the portal.

1B. That been said, you can concentrate on a subset of the problem: don't worry about multiple cameras, think instead in terms of only one camera active at any one time, and the capacity to change which camera is active. This way the render side of things is relatively untouched.

  1. I'd say it is -the- single, hardcoded, active camera. It is controlled by one or more systems (haven't gone that far up in the code, I normally lurk much deeper, in the pixel forge - WorldRendererImpl and below) but is not a component nor an entity. As far as I understand the systems controlling it update the camera's internal state directly, dependent on the data they find in the components of the player entity. Perhaps @Josharias can shed some light on the matter as I seem to remember he was the last one to touch that part of the codebase.

  2. I'm a bit confused by what you write and I need you to rewrite your thinking on this point, also in light of what I wrote above about thinking only in terms of one active camera for the time being. If still relevant.

  3. a camera would normally be an entity with at least three components: a LocationComponent (already existing) storing its world position, an OrientationComponent (already existing) storing its rotation and a CameraComponent storing information such as field of view/focal length and near/far distance. This could be a naive description though: in the process you might find more camera-specific components are needed/desirable. For example you might want to store the focal length value in a RealisticCameraComponent, the near/far distances in an OpenGLCameraComponentand, who knows, you might want to store/cache matrices in a "CameraCacheComponent". In this context I'd recommend to start simple and expand as needed and according to the feedback you receive.

Of course I remain available for further questions. Feel free to use this issue for further discussions. Alternatively you can open a thread in the forum or we can even arrange a meeting via irc if you'd like. Keep in mind I'm currently in holiday and I have some time in my morning and in my late evening. Next week I will be available only one hour in my early afternoon and then most evenings.

zeokav commented 7 years ago

Hi @emanuele3d . It's alright, haha! I appreciate the fact that you are taking some time off for this. Non immediate replies are not a problem at all. About the third bullet... That was the newbie question I was referring to. Might be a mistake in my understanding of the whole ECS paradigm. It was, in fact, a question regarding the behavior of the camera system in case of multiple cameras in the scene. I will bring it up when I'm working on multiple cameras, if I don't figure it out by then.

We should move this to the forum instead of cluttering the issue thread because I'm probably gonna need some more help. I'll post the forum thread link here when I make one. :)

EDIT: Link to thread