Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera Implementation #29

Closed
WozStudios opened this issue May 7, 2015 · 9 comments
Closed

Camera Implementation #29

WozStudios opened this issue May 7, 2015 · 9 comments

Comments

@WozStudios
Copy link
Contributor

I've been working on Camera functions, trying figuring out what they all do, and I thought I'd share what I've found, before I submit a pull request in a day or so when it's ready.

It seems there are at least 2 different types of cameras, the GameplayCamera, and scripted cameras created by scripts. Each have there own set of natives assosciated with them, and the ones for the GameplayCamera are pretty limited. It isn't possible to get a handle to the GameplayCamera, there are only a few functions that access and modify certain properties (GET_GAMEPLAY_CAM_COORD, GET_GAMEPLAY_CAM_ROT, etc).

There is a lot more control over scripted cameras. They can be created with CREATE_CAM or more often CREATE_CAM_WITH_PARAMS, which return an ID, it's possible to get/set most of their properties, interpolate between them, attach/lookAt targets, etc. Each creation function takes a string name, ie "DEFAULT_SCRIPTED_CAMERA", "DEFAULT_SPLINE_CAMERA", and a few others. I've only tested using "DEFAULT_SCRIPTED_CAMERA" so far, as it's the most commonly used one

Creating a camera sets it as active, but that's not enough for it to render. RENDER_SCRIPT_CAMS must be called. I'm not sure what all the params are, only that the first is a bool that sets whether to render scripted cameras or the GameplayCamera. Using the common values from the scripts for the others seems to work

There seems to be a hard limit of 26 scripted cameras that can be created at a time. After that, calling CREATE_CAM will return an invalid ID, until other cameras are destroyed with DESTROY_CAM

So far, I've wrapped most of the scripted camera functions into a Camera class. I made a static factory method, World.CreateCamera, as well as a few other static methods (eg, DESTROY_ALL_CAMS). I've also made a World::IsScriptCameraRendering property, that sets the RENDER_SCRIPT_CAMS native I mentioned

Unless someone objects, I'm going to make GameplayCamera an abstract class, similar to Game and World, as it only has a few static methods. I thought about making it a static property of Game, similar to Player, ie using it as Game.Camera, but I think that would be confusing for users, as it won't actually be a Camera object

Once I wrap the GameplayCamera, probably tomorrow, I'll make the pull request. After that, the remaining things that I see now would be:

-CameraShake
-CameraAnimation
-Special types of scripted cameras, ie spline, cinematic, I'm not sure at all how these work yet
-Any other natives I may have missed, as well as the unknown ones that are still hashed

Once this is in a release, I can share the Top Down mod I've been working on while researching all this =)

I'd be happy to hear any thoughts/suggestions anyone has about any of this

@JohnnyCrazy
Copy link
Collaborator

Nice research!

When this will be out, maybe I will do some kind of advanced Vehicle-Spawner with a vehicle preview 👍

@WozStudios
Copy link
Contributor Author

Okay, so all the basic features are done. I decided not to wait on CameraShake and added that in as well

Here's an example:

Vector3 position = Game.Player.Character.Position + new Vector3(0, 0, 10.0f);
Vector3 rotation = new Vector3(-90.0f, 0, 0.0f);
float fov = 50.0f;
camera = World.CreateCamera(position, rotation, fov);

// Must set this true to render script cameras, set to false to render GameplayCamera
World.IsScriptedCameraRendering = true; 

I wasn't sure whether to make it necessary for users to set World.IsScriptedCameraRendering or not. Maybe World should set it when creating a camera, and then it can keep track of cameras created, and when all are destroyed, it will set it to false. Or maybe just have it set it to true, and leave it up to the user to set it false when they want. Or we can leave it as is, whatever everyone thinks is best

GameplayCamera is pretty self explanatory, just some static methods, mostly getters

CameraShake types are represented with an enum, but the natives expect a string, so I matched them up to an array in an internal class CameraShakeNames, which isn't exposed in the API. I wasn't sure if this was the best way to do it, but it resulted in the API I was looking for:

For the scripted camera, I wrapped up the shaking functions in properties, and keep track of state internally. The CameraShake type is held in a ShakeType property, which defaults to CameraShake.Hand. The ShakeAmplitude property defaults to 1.0f. IsShaking starts/stops the camera shaking

camera.ShakeType = CameraShake.LargeExplosion;
camera.ShakeAmplitude = 10.0f;
camera.IsShaking = true;

For GameplayCamera shaking, I couldn't do the same thing, as the game can change these values, and there's no way of querying the current CameraShake/amplitude.

float amplitude = 10.0f;
GameplayCamera.Shake(CameraShake.LargeExplosion, amplitude);
bool isShaking = IsShaking; //readonly
ShakeAmplitude = 20.0f;     //writeonly
GameplayCamera.StopShaking();

@Nacorpio
Copy link
Contributor

Nacorpio commented May 8, 2015

This is really a very good research and job to say the least.
There are so many possibilities with this camera API, and I'm looking forward to playing around with it.

@ricci07
Copy link
Contributor

ricci07 commented May 9, 2015

Nice work woz, I couldn't find out how to use the camera functions. It's a pain when they have misnomer function names like SET_CAM_ACTIVE, when by definition it doesn't (Well at least not what you think it means)

@WozStudios
Copy link
Contributor Author

Thanks everyone. I agree, I think the potential of what can be done is petty cool. I'm thinking about maybe making something like Rockstar Editor, which I found to be a great idea, but still a little limiting.

I'm also seeing some RENDERTARGET natives. If we can figure out how to use them to render-to-texture from a camera, that would be incredible, but I'm not so sure that's possible

@crosire crosire closed this as completed May 9, 2015
@crosire crosire reopened this May 9, 2015
@crosire
Copy link
Owner

crosire commented May 9, 2015

Suggestion: Make World.RenderingCamera writable and in the setter make the passed camera active and enable script camera rendering. If assigning null disable script camera rendering.

@WozStudios
Copy link
Contributor Author

Ya, that sounds good. World.IsScriptCameraRendering seemed a little messy to me. I'll make the changes

@WozStudios
Copy link
Contributor Author

Okay, so World.IsScriptCameraRendering is gone. Now, World.RenderingCamera = camera sets camera as active, and sets script cameras rendering. World.RenderingCamera = null will switch rendering back to the GameplayCamera

@JohnnyCrazy
Copy link
Collaborator

Implemented long time ago in #33 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants