Archive

Archive for November, 2008

Salad Wrap

November 28th, 2008 admin No comments

This is just too funny:
“Shake, Shake, Shake”

Categories: Uncategorized Tags:

Computer Crimes

November 25th, 2008 admin No comments

My life can best be describe as “tech-nasty.” I eat, sleep, and breath technology. You know how some people enjoy the new car smell? I enjoy fresh silicon smell, the kind of smell that always comes with juicy new gadget or piece of hardware. And software, don’t even get me started. If I could I would print off all the source code in the world and make a giant bed out of it. Clearly if you read my blog even a little you’ll notice a “slight” tendancy toward the nerdlicious. (That’s my own neologism, feel free to use it.) Why am I telling you this? Because I want to frame what I say next with the understanding that I am first and foremost a pro-tech. guy. (For christ’s sake I’m a software engineer by trade.)

Technology isn’t always a good thing. Technology is, by and large, still highly misunderstood by the masses. The unfortunate part to all of this is that the law and the people who uphold the law (police and prosecution) can’t keep up. So what happens? What happens is an innocent woman looses 4 years of her life, her health, her teaching license, her community standing, and her child all because assumptions were made that couldn’t be backed up.

Actually I mispoke. The assumptions were backed up. Unfortunately they were backed up by a moron with just enough knowledge to be a threat but not enough to be effective. If you read the link above you’ll know that a police forensics “expert” supplied falsehoods that damned this poor woman to 4 years of legal hell. Example: Browser history doesn’t store redirects. Give me a fucking break. Of course it stores redirects, I’m pretty sure it has since the days of IE fucking 1. As Alex Eckelberry correctly points out:

It caught the media’s attention and the attention of forensic experts across the country because they all KNEW that typical behavior of a PC infected with malware is exactly what happened to Julie Amero in that classroom on that day.

Typical behavior. Anyone who has ever dealt with malware knows what it generally does and what happens to an infected PC.

It took the collective might of numerous technology experts around the country to finally provide evidence that this woman was a victim of piss poor IT. Even after that evidence was made public the prosecutor and police “expert” still believe they were in the right and that she is still guilty. Are they ignorant or are their egos too big to admit a failure to act with due diligence? Guilty until proven innocent, that’s sadly the new American way.

And at the end of it all this woman still doesn’t get her license back and she has to pay a fine. Of course she’s just happy that this is all over. That is a class act. This is one of the few times I think someone has a real reason to countersue. At the very least she is owed a public apology, 4 years of backpay, and her teaching license reinstated.

So here is the problem: Technology forensics should not have a grey area. Either you are an expert or you aren’t. Would you make someone an forensic pathologist if the only course they took was anatomy? Our legal system needs some streamlining or technology will continue to outpace the law by leaps and bounds. The same goes for so called police “experts.” It’s unfortunate that in this case the “expert” wasn’t even up to 1990 standards.

I love technology. I truly believe it enhances our lives and adds value to our society. Our generation is perhaps one of the most blessed in that we’ve been a part of one of the fastest moving renaissances ever. But as Uncle Ben from Spiderman says “With great power comes great responsibility.” We have a duty to make sure our experts are current and that laws at least try to keep up.

Categories: Uncategorized Tags: , ,

Ogre and Windows Forms

November 17th, 2008 admin 19 comments

3D editing software can be a pain to write. As opposed to games, editing software needs doesn’t require a frametick. It only needs to update when the scene changes or when the gui is move/resized/etc. In the past there have been some node based libraries such as OpenInventor or its follow up Coin3D. The problem is that these libraries weren’t focused on keeping up to date with graphics tricks like bump mapping or shaders. The other problem is that OpenInventor is mostly dead and Coin3D seems to have a very limited user base. (It also seems a tad dead.)

As you may have noticed from my previous posts I make use of Ogre3D in a lot of apps. Why should editing software be any different? The problem I found with Ogre is that the GUI systems available (such as CEGUI) aren’t quick to develop and they don’t provide much more than simple GUI elements and overlays. Enter Windows Forms. (Yeah I know Windows Presentation Foundations will take over soon enough but until then….)

OgreWrapperPic

So here is how to modify your code. First, start a completely new project using the Ogre wizard. This will give you an example to work from and I’m too lazy to post the code. Next you’ll want to create an OgreWrapper class. The idea here is that all of calls affecting Ogre go through this wrapper. It also acts as a buffer between managed and unmanaged code. Excuse the crude nature of my photo. 2 seconds in Paint will do that.

Ogre should have created a App class file for you. The header should look similar to:

#include <ExampleApplication.h>
 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//#include "../res/resource.h"
#endif
 
#include <CEGUI.h>
#include <CEGUISystem.h>
#include <CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>
 
class WFExampleFrameListener;
class WFExampleApp : public ExampleApplication
{
private:
     CEGUI::OgreCEGUIRenderer* mGuiRenderer;
     CEGUI::System* mGUISystem;
public:
    WFExampleApp();
    ~WFExampleApp()
     .....
}

Add an int value for the handle, change the constructor ,and add a resize and update function:

#include <ExampleApplication.h>
 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//#include "../res/resource.h"
#endif
 
#include <CEGUI.h>
#include <CEGUISystem.h>
#include <CEGUISchemeManager.h>
#include <OgreCEGUIRenderer.h>
 
class WFExampleFrameListener;
class WFExampleApp : public ExampleApplication
{
private:
     CEGUI::OgreCEGUIRenderer* mGuiRenderer;
     CEGUI::System* mGUISystem;
public:
    WFExampleApp(int _handle); //**NEW
    ~WFExampleApp()
    void Update(); //**NEW
    void Resize(int width, int height); //**NEW 
    .....
 
private:
    int mHandle;  //**NEW
}

and in the App.cpp file:

WFExampleApp::WFExampleApp(int _handle):mGUIRenderer(0),mGUISystem(0),mHandle(_handle){}

Now just modify the functions ‘Configure()’, ‘Resize()’, and ‘Update()’ in App.cpp:

WFExampleApp::Configure(){
     mRoot->restoreConfig();//Avoid launching options menu
     NameValuePairList miscParams;
     miscParams["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)mHandle);
     mRoot->initialise(this);
     mWindow = mRoot->createRenderWindow("ExampleApp",640,480,false,&miscParams);
     return true;
}
 
WFExampleApp::Resize(int width, int height){
     mWindow->resize(width,height);
     mWindow->windowMovedOrResized(); //Important, without this the rendering window won't update
}
 
WFExampleApp::Update(){
     mRoot->renderOneFrame();
     mWindow->update();
}

Now that you’ve got your App class setup properly you need to add ‘Update()’ and ‘Resize()’ to the OgreWrapper class. All they’ll be doing is pointing to the functions we just wrote for App. OgreWrapper must also pass the Windows Form handle to App when it is created.

Lastly, design your form. Create an empty form, now add a ‘panel’ to said form. The panel will be what houses Ogre’s rendering context. I labeled mine panelOgre (tricky no?.) All you need to do is call OgreWrapper and pass panelOgre->Handle.ToInt32() to it. This is the handle to be given to .app. That’s it. Just make sure any function that modifies the scene also calls OgreWrapper::Update() which in turn calls App::Update().

Damn I forgot one more thing. Add a ‘Timer’ to the Windows Form. It’s in the toolbox. If you right click on the ‘Timer’ you and click ‘Properties’ you can set an update interval. I set it to 15. You then need to click on the Events button of the properties (looks like a little lightning bolt) and add an event for timer_tick. In this event you need to call OgreWrapper::Update().

And there you have it. It’s crude but effective. I should note that you can probably get rid of the framelistener class. In my case it was just extra unnecessary code. All peripheral events are capture by the Windows Form. It’s your job to pass these calls to the OgreWrapper and then on to whomever needs the update.


*Edit: A request was made for the solution to this project. After a bit of digging I found my original example. Huzzah for that. Now for the bad news. This project was a test bed for how to dynamically load plugin’s from a core framework. That means there is a bit more code than isn’t necessary. The code is given freely as is, lack of comments and all. If you’ve set up an Ogre3D app. before this shouldn’t look new.

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

Categories: Uncategorized Tags:

Child’s Play Charity

November 9th, 2008 admin No comments

Penny Arcade’s “Child’s Play Charity” is open for donations.  I know that in the current economy it can be hard to find spare cash but please consider donating to this cause. Last year I believe they broke 1 million dollars in donations, lets see if we can’t break 2.

More information can be found on the official site.

Categories: Uncategorized Tags:

Obj To Havok hkx

November 6th, 2008 admin No comments

Last night I finally got around to pulling together disparate pieces of code to write a Havok exporter. In my original Havok/Ogre example I used the deprecated MOPP loader in GameUtils to load .hk files. (Part of my incorrectly named ObjToTk project.)

The files can be found here. As always the SVN login information is located on the left of my blog page; labeled ‘SVN Access’.

The code is hard to follow because I was testing features and just copying code around. The valid functions are Load and Save. You can also see how to reload an HKX file in the function LoadHkx.

Load:

void Load(const char *file){
	vector<string> tokens;
	string line;
 
 
	ifstream myfile (file);
 
	if (myfile.is_open()) {
		while (! myfile.eof() ) {
			getline(myfile,line);
 
			if(line.length() > 0) {
				Tokenize(line, tokens);
 
				if(line[0] == 'v' || line[1] == 'V'){
					Point *tmp = new Point;
					tmp->cell[0] = atof(tokens[1].c_str());
					tmp->cell[1] = atof(tokens[2].c_str());
					tmp->cell[2] = atof(tokens[3].c_str());
					_gvPoints.push_back(tmp);
					_nVtx++;
				} else 	if(line[0] == 'f' || line[1] == 'F'){
					Face *tmp = new Face;
					tmp->cell[0] = atof(tokens[1].c_str());
					tmp->cell[1] = atof(tokens[2].c_str());
					tmp->cell[2] = atof(tokens[3].c_str());
					_gvFaces.push_back(tmp);
					_nFace++;
				}
				tokens.clear();
			}
 
		}
 
		myfile.close();
		printf("loaded %d vertices\n",_nVtx);
		printf("loaded %d faces\n",_nFace);
	}
	else {
		printf("Unable to open file\n");
	}
	float radius = -1.0f;
	hkpSimpleMeshShape* meshStorage = new hkpSimpleMeshShape(radius > 0 ? radius : hkConvexShapeDefaultRadius);
	meshStorage->m_vertices.setSize(_nVtx);
	meshStorage->m_triangles.setSize(_nFace);
 
	for(int i = 0; i < _nVtx; i++){
		hkVector4 vertex(_gvPoints[i]->cell[0],_gvPoints[i]->cell[1],_gvPoints[i]->cell[2]);
		meshStorage->m_vertices[i] = vertex;
	}
	for(int i = 0; i < _nFace; i++){
		meshStorage->m_triangles[i].m_a = _gvFaces[i]->cell[0]-1;
		meshStorage->m_triangles[i].m_b = _gvFaces[i]->cell[1]-1;
		meshStorage->m_triangles[i].m_c = _gvFaces[i]->cell[2]-1;
	}
	hkpMoppCompilerInput mfr;
	mfr.setAbsoluteFitToleranceOfAxisAlignedTriangles( hkVector4( 0.1f, 0.1f, 0.1f ) );
	hkpMoppCode* pCode = hkpMoppUtility::buildCode( meshStorage, mfr );
	pShape = new hkpMoppBvTreeShape( meshStorage, pCode );
 
	pCode->removeReference();
	meshStorage->removeReference();
}

Save:

void Save(const char *file){
	HK_ASSERT2(0x64232cc0, pShape,"TK file failed to load to MOPP in GameUtils::loadTK2MOPP.");
 
	hkpRigidBodyCinfo ci;
	ci.m_shape = pShape;
	ci.m_motionType = hkpMotion::MOTION_FIXED;
	ci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( 0, 1 );
	//ci.m_position = hkVector4(pos.x,pos.y,pos.z);		//TODO:  Add ability for physics mesh to be positioned independent of ogre mesh.
 
	hkpRigidBody *_hkRigid = new hkpRigidBody(ci);
 
	hkBinaryPackfileWriter writer;
 
	writer.setContents( _hkRigid, hkpRigidBodyClass );
	hkPackfileWriter::Options options;
 
	hkOstream out(file);
	writer.save( out.getStreamWriter(), options );
 
	_hkRigid->removeReference();
 
}

LoadHkx:

void LoadHkx(const char *file){
 
	hkIstream *infile = NULL;
	printf("Infile created\n");
	try {
		infile = new hkIstream(file);
		HK_ASSERT2( 0xdbcf8c61, hkPackfileReader::FORMAT_BINARY == hkPackfileReader::detectFormat(infile->getStreamReader()), "File is not in the correct format");
		printf("Infile filled\n");
	} catch (std::exception ex){
		printf("Exception: %s\n",ex.what());
	}
	printf("Input stream created for %s\n",file);
	HK_ASSERT( 0x215d080c, infile->isOk() );
	hkPackfileReader* reader = new hkBinaryPackfileReader();
	reader->loadEntireFile(infile->getStreamReader());
 
	m_packfileData = reader->getPackfileData();
	m_packfileData->addReference();
 
	printf("Reader loaded\n");
 
	hkpRigidBody *body = (hkpRigidBody*)reader->getContents("hkpRigidBody");
	HK_ASSERT2(0xa6451544, body != HK_NULL, "Could not find rigid body in hkpPhysicsData" );
 
	_physicsWorld->addEntity( body );
	body->removeReference();
	delete reader;
}

My example uses binary output but Havok also supports XML output. Please note: Metadata (tags) are saved to the binary hkx files unless otherwise specified. Havok does contain an example on how to skip using metadata. It isn’t apparent but the line ‘write.setContents(_hkRigid, hkpRigidBodyClass)’ sets the metadata to type “hkpRigidBody.” Notice in my loader when I want to retrieve the data I use ‘reader->getContents(“hkpRigidBody”);’ Havok supports many different container classes as well as your own types.

Categories: Uncategorized Tags: