What my trig does is positions the camera on the edge of a sphere around the player rather than just the circle around the player on a flat plane. I guess its not a problem while you can only rotate your pitch but I think it would be best to get it in now before physics so we can see our work space easier. I can modify it for use like this (I believe this works with axis rotation - glRotatef): PHP: ... world.character.pos.z+=cos(angleY)*move; } //Compute where the camera is in relation to character double cameraDist = 6; //Code for rotating camera goes here (hook into SDL and change using mouse movement?) angleY = world.camera.rot.y*PI/180.0; double angleX = world.camera.rot.x*PI/180.0; world.camera.pos.x = (-sin(angleY) * cos(angleX) * cameraDist) + world.character.pos.x; world.camera.pos.y = (sin(angleX) * cameraDist) + world.character.pos.y + 1; world.camera.pos.z = (-cos(angleY) * cos(angleX) * cameraDist) + world.character.pos.z; Either way, this is still just a quick and dirty before matrices are implemented. I haven't looked into 3D matrices yet so I'm in the same position as you, Sofox :P
So I messed around with ideas for a HUD, and this is one of the designs I put together. It's very modern influenced, so I'll be working on something more retro influenced, as well as more drafts of this one. If you're interested in it, and if there are any changes you'd like to see made, let me know (The picture of the ring is just a place holder for now.)
Hang on a second. First-Person controls in a third-person game. Does that end up anything like MegaMan Legends? I'm really good at that, and come to think of it, it could be fairly useful for controlling Sonic. Can we keep that until we have the engine fleshed out more, and see if it's worth keeping as a setting?
Using the mouse for camera controls is the best method of controlling the camera in a 3D Sonic game, by far, in my opinion, for the same reason why it's the best control method for a shooter - precision and speed tied into one fantastic package, while also allowing for buttons to be on hand even when controlling the camera.
Exactly what Candescence said, however the key difference between a Sonic game and a third-person shooter is that in a TPS the player/gun is always aiming at where the camera is aiming - whereas in a Sonic game; Sonic may not always be looking in the same direction as the camera at all times. SonicGDK is the best modern example of what we're talking about Kharen. You can run around and the camera will follow Sonic keeping your viewport always looking ahead of Sonic OR you can move the mouse around manually and have a look around for yourself - even while running.
Modified the code for some copy-pasta: input.h PHP: #ifndef ME_INPUT #define ME_INPUT struct me_input { bool upPressed; bool downPressed; bool leftPressed; bool rightPressed; bool quit; int mouseRelX; int mouseRelY; int mouseX; int mouseY; }; me_input setupInput(); void processInput(me_input &input); #endif input.cpp PHP: #include "input.h" #include "SDL/SDL.h" me_input setupInput(){ struct me_input input; input.upPressed = false; input.downPressed = false; input.leftPressed = false; input.rightPressed = false; input.quit = false; input.mouseRelX = 0; input.mouseRelY = 0; input.mouseX = 0; input.mouseY = 0; return input; } void processInput(me_input &input){ SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: input.quit = true; break; case SDL_KEYDOWN: switch(event.key.keysym.sym){ case SDLK_UP: input.upPressed = true; break; case SDLK_DOWN: input.downPressed = true; break; case SDLK_LEFT: input.leftPressed = true; break; case SDLK_RIGHT: input.rightPressed = true; break; case SDLK_ESCAPE: input.quit=true; break; default: break; } break; case SDL_KEYUP: switch(event.key.keysym.sym){ case SDLK_UP: input.upPressed = false; break; case SDLK_DOWN: input.downPressed = false; break; case SDLK_LEFT: input.leftPressed = false; break; case SDLK_RIGHT: input.rightPressed = false; break; default: break; } break; case SDL_MOUSEMOTION: input.mouseRelX = event.motion.xrel; input.mouseRelY = event.motion.yrel; input.mouseX = event.motion.x; input.mouseY = event.motion.y; break; } } } main.cpp (only these three methods and class were changed) PHP: void update(me_input &input, me_world &world){ if(input.leftPressed) world.character.rot.y+=0.05; if(input.rightPressed) world.character.rot.y-=0.05; double angleY = world.character.rot.y*PI/180.0; if(input.upPressed || input.downPressed){ double move = input.upPressed ? -0.01: 0.01; world.character.pos.x+=sin(angleY)*move; world.character.pos.z+=cos(angleY)*move; } //Compute where the camera is in relation to character double cameraDist = 6; double angleX = world.camera.rot.x*PI/180.0; //Make new position with trig world.camera.pos.x = world.character.pos.x+(sin(angleY)*cameraDist * cos(angleX)); world.camera.pos.y = world.character.pos.y + 1 + (sin(angleX)*cameraDist); world.camera.pos.z = world.character.pos.z+(cos(angleY)*cameraDist * cos(angleX)); world.camera.rot.x += input.mouseRelY * 0.2; //No going higher than 90! if(world.camera.rot.x > 90) world.camera.rot.x = 90; if(world.camera.rot.x < -90) world.camera.rot.x = -90; //Last bits world.camera.rot.y = world.character.rot.y; input.mouseRelX = 0; input.mouseRelY = 0; } PHP: void render(me_world world){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //Camera control glRotatef(-world.camera.rot.y,0.0,1.0,0.0); //Some more trig for the local X axis - needs optimizing glRotatef(world.camera.rot.x,(cos(world.character.rot.y*PI/180.0)*cos(world.character.rot.x*PI/180.0)),0.0,-(sin(world.character.rot.y*PI/180.0)*cos(world.character.rot.x*PI/180.0))); glTranslatef(-world.camera.pos.x,-world.camera.pos.y,-world.camera.pos.z); //Begin rendering glBegin(GL_QUADS); glColor4f(0.1,0.8,0.0,1.0); glVertex3f(-100,0,-100); glVertex3f(100,0,-100); glVertex3f(100,0,100); glVertex3f(-100,0,100); glEnd(); renderCharacter(world.character); glBegin(GL_QUADS); glColor4f(1.0,1.0,1.0,1.0); glVertex3f(1,0,-12); glVertex3f(3,0,-12); glVertex3f(3,2,-12); glVertex3f(1,2,-12); glEnd(); glBegin(GL_TRIANGLES); glColor4f(1.0,0.9,0.5,0.9); glVertex3f(-20,0,12); glVertex3f(-20,0,14); glVertex3f(-20,10,13); glEnd(); glBegin(GL_TRIANGLES); glColor4f(0.2,0.9,0.57,0.9); glVertex3f(22,0,-45); glVertex3f(24,0,-45); glVertex3f(23,9,-45); glEnd(); glLoadIdentity(); SDL_GL_SwapBuffers(); } PHP: me_camera setupCamera(){ struct me_camera camera; camera.pos.x = 0; camera.pos.y = 1; camera.pos.z = 6; camera.rot.x = 0; camera.rot.y = 0; return camera; } I apologise for the huge post, I only did a few things: 1) Added a listener for mouse 2) Used the y mouse movement to change the X rotation of the camera 3) Used some trig to work out position of camera and the axis for X rotation. It now has a 3D orbiting camera. There is still a problem with the mouse though, I have no idea how to get input past the window box. I'll look into this later. After having a look at 3D rotational matrices, I have a feeling that while they will be cleaner they are also slightly more intensive than the method I have used here (this can still be optimised some more). I'm sure matrices will be better put to use for the character, enemies etc. but for a fixed object like the camera this is fine. EDIT: Sofox, I have signed up to Bitbucket. Is there anyway I can get added to the list so I can commit stuff straight to the main branch or would you rather I make a fork and have it pulled in?
Relick: Whoa, great work! I can give you write access to the respository, but you'll need to send me the email address you used for your BitBucket account. Instructions for making forks, modifying them, and creating pull requests to have them merged back can be found here, but I don't think we'll need to use that unless the suggested changes become really big. In terms of the camera debate, I have no problem with keeping FPS-style controls for now. We'll need to look at the various ways of controlling the character if we're going to figure out what the best method is (though we can certainly leave other methods available as an option). Kaze: That is NICE! Very stylish with a good colour scheme. If I had to suggest a few things, the colons could be more vertically centered, the shadows maybe a touch closer to the text and the number font could maybe be a bit... cleaner? Sorry, not sure if that's the right word, I'm not that experienced with design. In any event, it looks good, and it'll be great to have this in the engine!
(Sorry for double post, I'm just making an update on my commits) Committed these changes to the repo: SDL mouse monitoring 3D camera orbit (with switchable modes*) Fixed a Windows build problem Mouse locked into window FPS counter in title bar (for optimisation purposes) Some general optimisation involving trigonometry *If you press the key 'S' then you will change from these controls: Left/Right keys rotate character and camera (they are locked together), camera's x rotation is changed by moving the mouse on the Y axis. to these controls (and if you press it again you'll switch back): Left/Right keys rotate character ONLY, camera's rotation is changed via moving the mouse. Sofox, I have a couple of comments in there which you might want to look at. Nothing too important, just asking you where to put some variables and stuff.
Most (if not all) keyboard keys have been added to the listener KeyCodes enum added for easy access to keyboard keys. main.cpp updated for new input detection. Committed changes to the repo. I forgot to add mouse button input :P, I'll do that later. EDIT: Not too major so It's just an edit: Delta Time added (and used on the character/camera). Mouse button input is now recorded. Lerp added to the camera for left/right button rotation in order to feel slightly nicer to use :P Delay added to the while loop in order to prevent stupidly high framerates (e.g. mine was at 11,000). These have been committed. I don't think I'll change any more until we decide on what to do next, I think that's everything we need so far.
Hey Relick, thanks for the contributions. However, I'm finding the controls a bit more difficult to use now. The mouse is a bit oversensitive for one thing, and I just find I'm struggling with the controls more than just using them. I know you've just started developing it, but I'd prefer to keep the controls as seamless as possible through development, as we'll be doing a lot of testing in the engine that'll involve controlling character. I do appreciate the help though, thanks!
Code (Text): if(world.camera.controlModeMouse) { world.camera.rot.y += input.mouseRelX * -0.2; } You can change 0.2 to make it more or less sensitive. I've only tested the Windows build (and 2 other people), and it seemed fine on them so it may be something to do with Linux - although it could also be your personal preference. A video of it would help a lot.
I think the problem is more likely to be I've a RAT 7 mouse that's pretty sensitive. I also think the viewing angle is too wide since the camera can be moved "underground", but I think I see the code to fix that so don't worry.
Been a bit busy recently hence the lack of progress. Still fully intend to work on collision. I'm thinking the main character's collision mesh could be defined by a set of collision spheres (just one sphere to start things off. Thinking: -Firstly: Once the sphere come into contact with something, the movement for that step is reversed. -Then: Once the sphere collides with something, we halve the movement, and see if it is still colliding, otherwise we just reverse the move completely. -Then: Once the sphere collides with something, we try to make a best guess over where to reposition the item. Once we've got it done for the main character and moving around and bumping into things, I can work then on getting hills and slopes implemented into the terrain, and from then on into things like gravity and jumping. Relick, I've been thinking over the controls you implemented and I think I see what where it falls short. The movement and the camera controls are too divorced from eachother so you kinda have to work each independently at the same time. I'm thinking that if you could adjust the controls so they're more like Lugaru, where your movement takes into account where the camera is as well as which key you're pressing, then the controls would improve exponentially and we could have fluid controls and camera in one. Thanks!
I'll get onto it as soon as I have time, I have had quite a bit work of work recently too. I understand the controls are a bit awkward at the moment but I wanted to get something in so we had full view of the scene before we refined it.
Relick, that's cool. I understand what you were doing, and I really appreciate the work you put into this.
Well, honestly, I just want to have a degree of precision over the character's movements. Since that's one of the key parts of the game. I'm still thinking Bullet will be important, but more after we've developed the key movement mechanics.
I've added a collision sphere attribute to the camera. Working on a system to detect collision between that sphere and a 3d triangle.
There's a real life task that's been grabbing my attention recently. I'll aim to add some collision stuff by the weekend.