Archive

Archive for August, 2009

Ogre Windows Forms GUI

August 13th, 2009 admin No comments

ogregui

Awhile back I made a post on combining Ogre and Windows Forms. There was some interest both online and off and a request was made for the solution belonging to said project.

The solution can be found here. And as usual the instructions for accessing my SVN can be found here.

At the time of the initial writing my example was sparse. It launched an empty Ogre scene and we were done. My new example expands just a bit on the Ogre/Windows FORM GUI idea. The biggest addition is the ability to create new plugins. But let’s call a spade a spade, the additional “framework” is nothing more than a simple parameter structure and the a plugin base class specifier.

Additionally (for those who’ve never used Ogre3D) everything inside the Ogre3D engine can be access by Singletons. In other words if I create a mesh in my main program I know I’ll be able to snag it in a plugin as long as I know the exact name.

The basic idea is this. You have a set of unmanaged classes, an ogre frame listener and an ogre app. These handle the core of updating and manipulating Ogre. Around those classes is a managed OgreWrapper. This class is the interface between Windows Forms and the Ogre classes. It handles mouse/keyboard input, updating, and resizing. You also have a plugin manager that handles loading .dll’s and determining if they are valid.

Lord it’s fucking late, I’ll write up a proper tutorial this weekend. Until then please enjoy the free code and if you have questions let me know.

Oh and this was built against Ogre 1.6.3.

How to open an old school Win32 console in a Windows App:

void createConsole(){
	AllocConsole();
	SetConsoleTitle(_T("Fuck message boxes"));
 
	int hConHandle;
	long lStdHandle;
	FILE *fp;
 
	// redirect unbuffered STDOUT to the console
	lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
	fp = _fdopen( hConHandle, "w" );
	*stdout = *fp;
	setvbuf( stdout, NULL, _IONBF, 0 );
 
	// redirect unbuffered STDIN to the console
	lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
	fp = _fdopen( hConHandle, "r" );
	*stdin = *fp;
	setvbuf( stdin, NULL, _IONBF, 0 );
 
	// redirect unbuffered STDERR to the console
	lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
	fp = _fdopen( hConHandle, "w" );
	*stderr = *fp;
	setvbuf( stderr, NULL, _IONBF, 0 );
}
Categories: Coding Tags:

IE 7 Operation Aborted

August 11th, 2009 admin No comments

If you are an Internet Explorer user you may have been seeing a cryptic IE error: “Internet Explorer Failed to Load Internet Site… Operation Aborted.”

Apparently Lightbox 2.02 loads prior to the rest of the document and IE 7 and earlier do not allow scripts to modify parent documents.

I found a great little post that describes how to fix the problem as an admin. You can also disable the error checking as an IE user by following these instructions.

Categories: Uncategorized Tags:

Ogre Off Axis Camera

August 11th, 2009 admin 2 comments

Creating a CAVE using Ogre3D is a snap. Thanks in no small part to the work William De Jonge on the CaveUT Unreal mod. (A project I once worked on.) The idea is that each client camera is modified by shifting and/or rotating it’s frustum. In Ogre you can apply a custom projection matrix to achieve this effect.

First, we set up the off axis camera:

Ogre::Camera *_camera = mSceneMgr->createCamera("PlayerCam");
Ogre::Camera *_dummyCam = mSceneMgr->createCamera("DummyCam");
Ogre::SceneNode *_ubernode = mSceneMgr->createSceneNode("UberNode");
Ogre::Matrix4 _offAxis;
void EnableOffAxisProjection(){
	try {
		double pi = 3.14159;
 
                ///Hard code the fov values for now, in your program these would be read from an .ini or something.
                double dfov = 90,dfovleft=-45.0,dfovright=45.0,dfovtop=34.0f,dfovbottom=-34.0f;
                double dyaw = 0.0f; ///Frustum rotation
 
                ///field of view in the y axis.
		double dfovy = 2*atan( tan(/2 * pi/180) / _camera->getAspectRatio() )*180/pi;
		_camera->setFOVy(Degree(dfovy));
 
		_camera->setCustomProjectionMatrix(false);
		double n = _camera->getNearClipDistance();
		double f = _camera->getFarClipDistance();
		double l, r, b, t;
 
		l = n*tan(dfovleft*pi/180);
		r = n*tan(dfovright*pi/180);
		b = n*tan(dfovbottom*pi/180);
		t = n*tan(dfovtop*pi/180);
 
		//Small modification from original off-axis algorithm.  Signs of certain vars were changed so the Y rotations aren't flipped.
		//This also fixes the problem of translations moving in the incorrect direction.
		_offAxis = Ogre::Matrix4(		(2.0f*n)/(r-l), 0,				((r+l)/(r-l)),	0,
										0,				((2.0f*n)/(t-b)), ((t+b)/(t-b)),	0,
										0,				0,				-(f+n)/(f-n),	-(2.0f*f*n)/(f-n),
										0,				0,				-1,				0);
		_offAxis.transpose();
		_camera->setCustomProjectionMatrix(true, _offAxis);
 
		//TODO:  Support pitch and roll at some point, for now yaw is the only important value.
		_camera->yaw(Degree(dyaw));
 
		_uberNode->attachObject(_camera);
	} catch (Ogre::Exception *ex){
		printf("ERROR - Trouble creating off axis projection: %s\n",ex->getDescription().c_str());
	}
}

As you can see, I have hardcoded the field of views. For a better understanding of where these values come from please see my link to CaveUT. Jeffrey Jacobson (the author of CaveUT) has a set of tutorials explaining how to calculate fields of view.  Keep in mind these values are completely dependent on the physical CAVE setup as well as the user’s position in the environment.

We aren’t doing anything crazy here. We simply create a custom view matrix using our FOV inputs and some information about the current clip planes. We assign that new matrix to the off axis camera and we then yaw the camera (in my example yaw is 0) and we attach this camera to an “ubernode.“  Think of the uber node as the player’s body.  When we rotate or translate this is what we update.(More on this after the next chunk of code.)

Next we provide a mechanism for moving the off axis camera:

void MoveCamera(Ogre::Vector3 rot, Ogre::Vector3 trans){
	if(!_bStart)return;
	try {
		//Rotate the uber camera node which in turn rotates all sub cameras
		_uberNode->pitch(Ogre::Radian(rot.y) * -1, Node::TS_LOCAL);
		_uberNode->yaw(Ogre::Radian(rot.z), Node::TS_WORLD);
 
		//Rotate dummy camera.  The dummy camera does not display anything on the screen.  What it does is take the same rotations that would be
		//applied to the uber node and it points along the same direction.  We can then use 'MoveRelative' of the dummy camera to get movement along the uber node's
		//line of sight.
		_dummyCam->roll(Ogre::Radian(rot.x));
		_dummyCam->pitch(Ogre::Radian(rot.y));
		_dummyCam->yaw(Ogre::Radian(rot.z));
		_dummyCam->moveRelative(trans);
 
		//Adjust the uber node accordingly.
		_uberNode->setPosition(_dummyCam->getPosition());
	} catch (Ogre::Exception *ex){
		printf("  ERROR - Trouble moving off axis projection: %s\n",ex->getDescription().c_str());
	}
}

Moving an off axis camera is slightly different than moving a regular camera. The off axis camera, assuming it has been yawed, is facing a different direction than the player.  Remember that in a CAVE all of the cameras work together to create a single view.  Moving a character “forward” for example should move all of the CAVE views “forward” relative to the player, not to their respective views.

So we create a dummy camera, set to the initial player view(which I didn’t show in my example).  Instead of allowing the Ogre::FrameListener to directly update the player camera we tell it to call our MoveCamera method above.

What does MoveCamera() do?:  Remember the uber node I mentioned above and how it represents the players “body”?  We first update this node with any rotations that have happened since the last frame tick.  Next we update our dummy camera.  Think of the dummy camera is the player’s “eyes.”  The dummy camera is rotated first and then translated along it’s view, this view should inherently correspond to where the player is looking in to the CAVE.  We then apply this translation to the uber node and that in turn updates the actual off axis camera.

We do this for 2 reason:  First, if we simply translate the off-axis camera it will move relative to it’s own view direction and not that of the player.  Secondly because SceneNode’s dont’ have a move relative function.  If you were so inclined you could remove my dummy camera and replace it with a class that transforms a ray and moves relative to that ray.  I just wanted to make it easy by using an existing Ogre class.

That’s it, we’re done.  Just make sure the Ogre::Framelistener updates MoveCamera() every tick and you’ll be good to go.

————————

*** A word of caution:  If you haven’t ever set up a CAVE you are doing yourself a disservice by not reading the relevant literature.  Just copying my code above is enough to get a start but without understanding the math or how to calculate FOV values you’ll be left wondering why your scene looks funny.  Make sure you calculate FOV values from your player’s actual eye level (known as the sweet spot).  The easiest test is to create a 3D  horizontal line.  If you look at that line in your CAVE from anywhere bu the sweet spot it will look bent.  As you approach the sweet spot the line will gradually look straighter until it looks exactly like a straight line even though it spans multiple screens.

Categories: Uncategorized Tags:

PC Colored Glasses

August 9th, 2009 admin No comments

Coding Horror did a great little story on the Evony ads you have probably seen floating around. They look like this:
evony-ad-5

Take a look at Jeff Atwood’s post above and look at the progression from relevant to outright lie. And in case you are wondering, this is what the game actually looks like:
Evony

I don’t see any semi-nude women… maybe they’re indoors or off servicing the “lord.” All 16-bits of them. At that resolution it’s what, maybe 4 pixels per breast? Like some sort sexy tetris side boob. If you blur it enough it could be sexy, nothing hotter than a Gaussian filter.
pixel_sideboob

Where is the subtlety, the romance, the raw passion? As lord of a kingdom I don’t want women just throwing themselves at my feet. I want to do what all great lords have done, I want to subjugate the populace and pillage what I want, women included. It’s a good thing I’m not a feudal lord, I’m pretty sure if I tried to kidnap my fiancee from the streets she’d beat the piss out of me.

Personally I think the ads should have gone a different route. It’s all about truth in advertising:
evony_gross
*Jack pot.

Book store Odin

August 7th, 2009 admin No comments

stevodin.

In to fantasy/sci-fi books? Have a few hundred bucks, some spare time, and live in MA?

If so then do yourself a favor and go to the ‘Barnes and Noble’ bookstore on rt. 9 in Framingham on a Friday/Saturday around 7ish. Stand in the sci-fi section and look for the towering bombastic voiced juggernaut of book suggestions. He goes by the name of Steven and trust me, you’ll walk out with more books than you ever wanted.

I met Steven a few years ago while looking for some new books to read. His genuine love of sci-fi books seems to overcome what would others would consider “social etiquette.” In other words he’ll walk up and start talking regardless of your relationship. I’m glad that I didn’t blow him off though. His suggests have kept my reading queue full for almost 2 years and maybe 90% of them are stellar reads.

But be warned. Tis’ not for the faint of heart for whom I suggest this weekend dalliance. Steven’s afore mentioned lack of social grace requires one to be…. forceful in their goodbyes. I learned this hard way after spending about $200 dollars in a single shot. If this guy is part of some ‘Barnes and Noble’ scheme to sell books, it works.

Also, on the topic of fantasy books. Why must the covers be so fucking flowery? It’s like the publishers want to keep nerds unfulfilled in the bed room. Thank god I’m engaged. Admittedly even she will withhold sex until I remove a particularly fey looking dust jacket

Categories: Uncategorized Tags: