1
SFML projects / Drawing a 3d world using SFML and a perspective tranformation.
« on: February 06, 2024, 04:13:21 am »
I took this on just to see what I would get graphically, and boy did it take off! I now have my own little 3d world to do physics stuff in!
Here's a bandicam recording of play.
It shows most of the good stuff in rapid fashion, but there's much more. I added a help menu for myself as I was losing track of keyboard shortcuts to the various features.
I'll get into some coding details here soon. Briefly, the (abstract) base class persPt (perspective point) for all 3d drawable objects has static members which build in a camera coordinate basis which are rotated to achieve yaw, pitch and roll. I've really been discovering the utility of static class members in recent projects. Here, the camera position and orientation are available in the member functions of all derived drawable types, which makes it straightforward to have each type fully manage its own state. I've achieved some optimizing in my z-ordering, eg. to sort a container of pointers to type persPt which is a shortlist of only those to be drawn this frame, etc.
I'll post some actual code shortly. I do post rarely but I've been quietly chugging away at projects using SFML. I have a solid appreciation for such an easy to use API (for the basics). For comparison, I did my 1st animated space shooter (2d) about 20 years ago.
I used Windows GDI. The OLD stuff, pre GDI+. I hated having to spend 80% of my time coding for the graphics when it's the other 20% that's the important part!
I have a memory leak bug story from that project for another time, except to say that ever since my programs allow the 'esc' key for quitting.
Edit: for further content. I'm quite lost here. I hope this is an intended means to continue. Here's a try at posting code. This is the static persPt function which transforms a 3d position to the required (x,y) position in the window.
I think I'd better go study a wiki here now.
edit: I've attached my solution to the math problem. The code for get_xyw() is based on it.
Here's a bandicam recording of play.
It shows most of the good stuff in rapid fashion, but there's much more. I added a help menu for myself as I was losing track of keyboard shortcuts to the various features.
I'll get into some coding details here soon. Briefly, the (abstract) base class persPt (perspective point) for all 3d drawable objects has static members which build in a camera coordinate basis which are rotated to achieve yaw, pitch and roll. I've really been discovering the utility of static class members in recent projects. Here, the camera position and orientation are available in the member functions of all derived drawable types, which makes it straightforward to have each type fully manage its own state. I've achieved some optimizing in my z-ordering, eg. to sort a container of pointers to type persPt which is a shortlist of only those to be drawn this frame, etc.
I'll post some actual code shortly. I do post rarely but I've been quietly chugging away at projects using SFML. I have a solid appreciation for such an easy to use API (for the basics). For comparison, I did my 1st animated space shooter (2d) about 20 years ago.
I used Windows GDI. The OLD stuff, pre GDI+. I hated having to spend 80% of my time coding for the graphics when it's the other 20% that's the important part!
I have a memory leak bug story from that project for another time, except to say that ever since my programs allow the 'esc' key for quitting.
Edit: for further content. I'm quite lost here. I hope this is an intended means to continue. Here's a try at posting code. This is the static persPt function which transforms a 3d position to the required (x,y) position in the window.
// get the window position from the vec3f position in the scene
sf::Vector2f persPt::get_xyw( vec3f Pos )
{
vec3f Rcp = Pos - camPos;// from camera to Pos
float U = Rcp.dot( camDir );// projection along camDir = "z - Zcam"
vec3f Rcp_perp = Rcp - U*camDir;// component of Rcp in plane perpendicular to camDir
vec3f L = ( Z0/U )*Rcp_perp;// perspective transform applied
if( U < 0.0f ) L *= -1.0f;
// vec3f L = ( Z0/Rcp.mag() )*Rcp_perp;// perspective transform applied
return sf::Vector2f( X0 + L.dot( xu ), Yh - L.dot( yu ) );
}
The offset is to the crosshair position = center of window. Also, the '-' sign on the y component is the only place in the project where my choice of y axis up has to resolve to graphics reality. The vec3f type is just a math vector type of mine. This project is very heavy with vector based math problems. It's been a great exercise for those skills!sf::Vector2f persPt::get_xyw( vec3f Pos )
{
vec3f Rcp = Pos - camPos;// from camera to Pos
float U = Rcp.dot( camDir );// projection along camDir = "z - Zcam"
vec3f Rcp_perp = Rcp - U*camDir;// component of Rcp in plane perpendicular to camDir
vec3f L = ( Z0/U )*Rcp_perp;// perspective transform applied
if( U < 0.0f ) L *= -1.0f;
// vec3f L = ( Z0/Rcp.mag() )*Rcp_perp;// perspective transform applied
return sf::Vector2f( X0 + L.dot( xu ), Yh - L.dot( yu ) );
}
I think I'd better go study a wiki here now.
edit: I've attached my solution to the math problem. The code for get_xyw() is based on it.