Game Development Community

Tilting the camera / TGB Kart

by Chris Jorgensen · in Torque Game Builder · 07/29/2008 (11:15 pm) · 47 replies

I'd like to be able to tilt the camera such that a tile or sprite would be displayed at an angle. Here's a simulated effect:

www.xenoclone.com/images/crate.png www.xenoclone.com/images/road.png

I want to be able to all the normal things with the scene / objects... rotate the sprites, put layers of sprites, etc, etc.... just with the camera "tilted." I've been poking around in the code briefly and have stumbled across classes like t2dSceneWindow with the struct tCameraView, as well as t2dSceneObject, etc, etc.

So I have a few questions:

1- Where would I go to do this? Rotate the scene object or modify the camera view?
2- Within the selection from (1), what functions / parameters should I be looking at?
3- Are there any other modifications I'd need to do to get this to display correctly?

I'm hoping someone out there's knowledgeable in this stuff. I'm fairly raw on openGL, etc, so any pointers would be great!
Page «Previous 1 2 3 Last »
#1
07/29/2008 (11:48 pm)
You probably already know this, but, if you can do this by modifying the artwork in photoshop, you can save yourself some work.

I don't know exactly what that effect is called (skew/distort/?), but perhaps you could add a method to t2dSceneObject that would turn it on and give it a value/magnitude.

Then you need to modify t2dStaticSprite's rendering code to take that "skew" amount into account... I haven't looked at the low level "renderBitmap" methods in a while, but if you follow the chain eventually some form of "renderBitmap" is called from t2dStaticSprite. You can either find the right renderBitmap method or perhaps you will need to write you own that renders a bitmap to an arbitrary 2D quad, or takes a "skew" value and does that internally.

Then if you want this to also skew the collision shape, gah, that could be a really big pain. If its a sprite with a collision polygon I can see how you might move the nodes around to achieve the effect, but a circle collision shape just wouldn't work, unless you wan to to dive into the t2dPhysics collision detection code.

I don't see how you could do that on the t2dSceneWindow level. Everything is rendered separately so you can't just do this effect on the whole window after the fact. Maybe you could have a "setPerspectiveSkew" method on the sceneWindow that in turn just sets in on all its contained sceneObjects... But I think t2dSceneObject and t2dStaticSprite is where you need to look. Particularly the rendering methods for t2dStaticSprite.

Actually perhaps setting the "perspectiveSkewMagnitude" IS done on the sceneWindow level and just saved IN the sceneWindow as a member/field. Then when a sceneObject renders it accesses its contained sceneGraph->attached sceneWindow, and takes that value into account. Just another possibility...
#2
07/30/2008 (3:09 pm)
James... Thanks for the response. Naturally, I know how to skew art in photoshop... see my example. :) But the reality is I literally need the entire scene to be tilted, with a distance between the bottom of a sprite being "closer" to the camera than the top of the sprite.

Is there no "camera" used to view all objects? My understanding is that TGB is a stripped down 3D engine. And that openGL always has a view that's used to project the 3D to 2D. Is that not the case?
#3
07/30/2008 (3:31 pm)
I don't believe the scenegraph is rendered to a polygonal plane that you can skew. I could be wrong, though. I haven't actually dug into the C++ source on that level.
#4
07/30/2008 (4:19 pm)
The camera is inside t2dSceneWindow. TGB objects are 2D object that exist in a 2D scene and are rendered in 2D. They do not exist in a 3D scene that just happens to be flat. I honestly don't know where you would start to add 2.5D support to TGB, but its not going to be a one line change. On the other hand, it would be pretty damn cool.
#5
07/30/2008 (9:03 pm)
Ok. I'll keep poking around. I appreciate the feedback from you both. I'm still pretty raw on openGL, so this will be a good opportunity for me to learn up a little bit. I'll post results if I figure anything out.
#6
07/31/2008 (11:28 pm)
Got it to work. Not many lines of code at all. 4 are needed to force it to do the tilt all the time. A few more just to wrap a flag setting around it. Here's a pic below. I'll probably do a tutorial type post when I get something going. :)

www.xenoclone.com/images/mode7_example.jpg
#7
08/01/2008 (10:12 am)
Wow, holy crap. Are you doing that effect on a t2dTileLayer or on the whole t2dSceneWindow? You got me interested...

If that visual effect is completely separate from the 2D representation of sceneObjects, then collision/etc could potentially just work.

Hmmm, imagine the possibilities, could use that effect for the world map of your RPG, or a racing game...
#8
08/01/2008 (12:53 pm)
@James... it's 100% just a display thing. I haven't tested it too much yet. 2 lines of code were used to put perspective on the scenewindow, then 2 more to get the tile layer to do the same.

I'm actually thinking about doing something like F-Zero on the old SNES. :D But this could be a trick, if done right, that would just be too dang cool not to share.
#10
08/01/2008 (2:24 pm)
If this doesn't affect the rest of the inner workings, but only tilts the display, I'd be very interested in the changes.
#11
08/01/2008 (7:38 pm)
Yes please share the changes if they are really that simple. I want to make a mario kart clone! :P
#12
08/01/2008 (9:12 pm)
Defiantly impressive.
#13
08/04/2008 (6:35 pm)
Here's an update pic. It's basically 3 scrollers, two bitmaps, and then the script to enable the tilt, steer the invisible driver, etc... I'll put a youtube video up after the next iteration. Right now it steers around with pretend physics... the background moves as you turn, etc. Very Super Nintendo. :)

www.xenoclone.com/images/mode7_preview_2.jpg
I'm excited to turn this one into a tutorial eventually. I've been waiting for a "give back" sort of project. :D
#14
08/04/2008 (6:41 pm)
That is so awesome...
#15
08/04/2008 (9:33 pm)
And here's it on youtube, TGB Kart: www.youtube.com/watch?v=9zhrjrEFgmg

Here's good ol' Mario Kart, to see what I'm striving for: www.youtube.com/watch?v=sfd0MrC1X4U&feature=related

It's got a long way to go... but, it's come a long way since my initial question. :D
#16
08/04/2008 (9:43 pm)
Nice! This could really open up a lot more possibilities for TGB. I hope you can get around to making a tutorial or posting more info about how you did this.

Will this work with tilemaps too? If so that would be really interesting to me :)
#17
08/05/2008 (10:38 pm)
Here's an updated video on youtube.

@Joe: I have put a perspective on tiles before, but that's not what I'm doing in my current attempt in the video above. It should be able to work though in a similar fashion... my first screenshot is tiles.

Update Pic:

www.xenoclone.com/images/tgb_kart_t1.jpg
#18
08/08/2008 (1:30 pm)
Where are my manners? I should just show people *at least* how I've tilted the camera and all that. I did this in TGB 1.1.3. So I'm not sure if anything has changed in newer versions.

In your t2dSceneWindow.h, add the following items to the class (in the appropriate sections):

// Mode 7 view flag
	bool				mMode7;

	//Mode 7
	void setMode7Camera();

In the t2dSceneWindow::onRender function, go down to about where you see these lines:

// Calculate current camera View ( if needed ).
    calculateCameraView( &mCameraCurrent );

    // Setup new logical coordinate system.
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

And add this afterwards:

//skew perspective
	/*
	    gluPerspective( fovy, aspect, zNear, zFar )
			fovy = field of view, in Y direction, in degrees
			aspect = aspect ratio (X:Y) of window
			zNear = distance to near clipping plane
			zFar = distance to far clipping plane
	*/
	if(mMode7)
		gluPerspective(65, 1.333, 0.01, 32);

Now go down and find this code:

// Setup new viewport.
    dglSetViewport(updateRect);

    // Set ModelView.
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

And put this right above those lines:

//rotate camera... 45 is as low as it goes
	if(mMode7)
		glRotatef(-45.0f, 1.0f, 0.0f, 0.0f);

Also add this wherever you like within your class:

void t2dSceneWindow::setMode7Camera()
{
	mMode7 = true;
	return;
}

Then in your console functions, add this:

//----------------------------------------------------------------------------
// Set Mode 7 Camera Mode
//----------------------------------------------------------------------------

ConsoleMethod(t2dSceneWindow, setMode7Camera, void, 0, 0, "Set mode 7 camera")
{
	object->setMode7Camera();
	return;
}

Now in script, when you create a sceneWindow, you can do the following to tilt the view:

//enable tilt
    sceneWindow2D.setMode7Camera();

   //put the camera a little closer to the ground
    sceneWindow2D.setCurrentCameraPosition("0 14");

For the ground, I control the scroll speed/angle of scroller. For the kart, I used a non-tilted layer and a sprite.

I hope this is enough to get you started! I'll put together a better kit / tutorial once I've solved all the remaining problems of objects on the course. (I've already got a lake that'll splash around the kart when driven over. But other karts, trees, etc.. I haven't done.)
#19
08/08/2008 (2:50 pm)
That's got to be one of the coolest innovations I've ever seen in TGB--and pretty awesomely elegant as well!
#20
08/08/2008 (6:02 pm)
It seems to work but I can't use my sceneobject based GUIs with it, and tilemaps don't seem to be affected by the changes at all. Still very cool though! Thanks for sharing this :)
Page «Previous 1 2 3 Last »