# Sonic and Sega Retro Message Board: General Progress Thread - Sonic and Sega Retro Message Board

• 5 Pages
• 1
• 2
• 3
• 4
• Last ►

## General Progress Thread

### #16Sofox  Posted 30 November 2012 - 07:45 AM

• Posts: 86
• Joined: 26-March 12
• Gender:Male
• Location:Ireland
Added basic rotation of the character, changes pushed to repository.

Next up, orbiting camera.

While I'm working the controls out, my short term aim is Max Payne style controls (FPS controls with a 3rd person perspective on the camera), then we can develop into more 3d platformer style controls.
This post has been edited by Sofox: 30 November 2012 - 07:49 AM

### #17Relick  Posted 30 November 2012 - 03:09 PM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5

Sofox, on 30 November 2012 - 07:45 AM, said:

Next up, orbiting camera.

Don't know if you have figured this out yet, but here is a trig solution (I assume a matrix option would be better, though):

Assuming we know the rotation (this will be generated through the engine/changed using the mouse)

float x = 0;
float y = 0;
float z = 0;
float distance = me_character.camDistance;
float xA = cam.rotation.eulerAngles.x;
float yA = cam.rotation.eulerAngles.y;

x = -Mathf.Sin(yA) * Mathf.Cos(xA);
y = Mathf.Sin(xA);
z = -Mathf.Cos(yA) * Mathf.Cos(xA);

cam.position = new Vector3(x, y, z)  * distance;
cam.position += me_character.position

I'm not sure how OpenGL handles angles so that is using standard Euler angles and some of the negation might have tp be changed but its obvious where I'm getting at.

EDIT: Fixed it again :P
This post has been edited by Relick: 30 November 2012 - 06:26 PM

### #18winterhell  Posted 30 November 2012 - 03:18 PM

• Posts: 1138
• Joined: 16-October 10
• Gender:Male
Using matrices would definitely be cleaner approach, though the resulting outcome is the same.
Btw you should be wary of the way the axises work in OpenGL(and DirectX for that matter). Y is UP, despite what many people may tell you. They just artificially swap the letters for Z and Y in the 3D modelling programs because if Z is UP then some things are not possible, like doing a barrel roll with the camera. So when you load a model you may need to switch them, and maybe even negate one of them due to using left or right handed angles.

### #19Relick  Posted 30 November 2012 - 03:26 PM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5

winterhell, on 30 November 2012 - 03:18 PM, said:

Using matrices would definitely be cleaner approach, though the resulting outcome is the same.
Btw you should be wary of the way the axises work in OpenGL(and DirectX for that matter). Y is UP, despite what many people may tell you. They just artificially swap the letters for Z and Y in the 3D modelling programs because if Z is UP then some things are not possible, like doing a barrel roll with the camera. So when you load a model you may need to switch them, and maybe even negate one of them due to using left or right handed angles.

I've always assumed Y to be up and all those 3D programs to be wrong :P. That method works for y = up.

EDIT: Or rather, y = pitch = up
This post has been edited by Relick: 30 November 2012 - 03:30 PM

### #20Sofox  Posted 30 November 2012 - 06:46 PM

• Posts: 86
• Joined: 26-March 12
• Gender:Male
• Location:Ireland
Alright, I've added the camera orbiting, a few more items to the area to populate the scene a bit more, and did a bit more code cleanup. Changes pushed.

Relick & winterhell: Yes, I think that Matrices would be better for handling rotation, but truth is I'm a little rusty on matrix rotation, so I wanted to just get it working with minimal hassle. I'll probably revise it at a more appropriate time.

Relick: Currently, glRotatef handles it so that the first parameter gives the degrees of rotation (in degrees), and the following 3 parameters describe the axis that the rotation is meant to be around.

Basic movement is now done, time to work on basic physics. Time for researching and implementing collision detection.
This post has been edited by Sofox: 30 November 2012 - 06:47 PM

### #21Relick  Posted 30 November 2012 - 07:07 PM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5

Sofox, on 30 November 2012 - 06:46 PM, said:

Alright, I've added the camera orbiting, a few more items to the area to populate the scene a bit more, and did a bit more code cleanup. Changes pushed.

Relick & winterhell: Yes, I think that Matrices would be better for handling rotation, but truth is I'm a little rusty on matrix rotation, so I wanted to just get it working with minimal hassle. I'll probably revise it at a more appropriate time.

Relick: Currently, glRotatef handles it so that the first parameter gives the degrees of rotation (in degrees), and the following 3 parameters describe the axis that the rotation is meant to be around.

Basic movement is now done, time to work on basic physics. Time for researching and implementing collision detection.

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):

...
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
This post has been edited by Relick: 01 December 2012 - 04:14 AM

### #22TheKazeblade  Posted 30 November 2012 - 09:59 PM

• "Our Life is More than a Side-Effect"
• Posts: 2653
• Joined: 05-April 10
• Gender:Male
• Location:West Coast, US
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.)

This post has been edited by TheKazeblade: 30 November 2012 - 10:59 PM

### #23Kharen  Posted 30 November 2012 - 10:16 PM

• Posts: 606
• Joined: 29-October 11
• Gender:Male
• Location:Eastern Washington University
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?

### #24Candescence  Posted 01 December 2012 - 12:46 AM

• Posts: 1939
• Joined: 22-October 10
• Gender:Male
• Location:Sydney, Australia
• Project:3D Indie Stuff
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.

### #25Relick  Posted 01 December 2012 - 04:14 AM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5
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.
This post has been edited by Relick: 01 December 2012 - 08:45 AM

### #26Relick  Posted 01 December 2012 - 08:31 AM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5
Modified the code for some copy-pasta:

input.h
#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
#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)
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;
}

void render(me_world world){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

//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
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);

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();

SDL_GL_SwapBuffers();
}

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?
This post has been edited by Relick: 01 December 2012 - 08:45 AM

### #27Sofox  Posted 01 December 2012 - 10:24 AM

• Posts: 86
• Joined: 26-March 12
• Gender:Male
• Location:Ireland
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!

### #28Relick  Posted 01 December 2012 - 11:33 AM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5
Thanks, sent it to you.

### #29Relick  Posted 01 December 2012 - 04:51 PM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5
(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.
This post has been edited by Relick: 01 December 2012 - 04:52 PM

### #30Relick  Posted 02 December 2012 - 06:54 AM

• Posts: 197
• Joined: 20-March 10
• Gender:Male
• Location:England
• Project:C++/DX10 Engine (not sonic related)
• Wiki edits:5
• 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.
This post has been edited by Relick: 02 December 2012 - 12:34 PM

• 5 Pages
• 1
• 2
• 3
• 4
• Last ►