Friday, April 20, 2012

Qt, OpenGL and VS2010 How To

Resources:
My guide:

First, install [1]. Next install [2]. After that, you can notice a new Qt button at the top of your VS2010 toolbar. I haven't had to use the button for anything yet but know that it's there.

Development for me using Qt and VS2010 involves using VS to program my widgets and QtDesigner to create the UI layout.

You can open up your file.ui for designing by:
  • Double clicking it in your VS2010 Solution Explorer.
  • Or by opening QtDesigner directly, finding the file.ui of your project in Explorer, and using the designers opening dialog to go to that path and open it.
I normally use the 2nd longer direct approach.

While following the Zhao Wuluo walkthrough something to look out for is the mainwidget.cpp constructor:

MainWidget::MainWidget(QWidget *parent, Qt::WFlags flags)
 : QWidget(parent, flags),
 ui(new Ui::mainwidgetClass)
{
 ui->setupUi(this);
}


That's what my constructor looks like. The auto-generated class file lacked the ui(new Ui::mainwidgetClass) constructor call and this caused my GLWidget to throw an access violation error when being constructed itself. So don't do that, construct your ui.

Thoughts on beginning Qt:

It's nice. It can seem very overwhelming at first but I believe it's a matter of how you look at it. Let go of the idea of the GUI writing itself completely through the designer. Accept the idea that the entire endeavor is regular code and brackets programming with a nice designer tool to help where it can. Also, be sure to check out the "Qt Examples and Demos" app that comes installed with your SDK because running them and checking out their documentation in the QtAssistant has helped me a lot.

I will post more as I learn more. I hope this was helpful.

Sunday, April 1, 2012

Havok Tutorial: A way to detect bullet collisions

Hey. This will be less of a tutorial and more of a "here's a way to do something".

One way you can detect your bullets hitting objects in Havok is through the use of Phantoms. These are aabb's that exist simply to report what collides with them (and to apply events to those colliding objects if you'd like). This makes Phantoms great for things like triggering events based on a player's location, and bullets.

Check out the demo at: Demo\Demos\Physics\Api\Dynamics\Phantoms\PhantomObject for example code on using Phantoms.

So for example, you can draw your bullets as particles, and maintain a phantom for each of these bullets. When a bullet phantom's collision list contains an enemy you can say doBulletHitEnemy() or whatever.

Tuesday, March 27, 2012

Havok Tutorial: Detect a ball bounce.

So lets say you have several balls bopping around your scene. Or heads. Or grenades. Whatever. And you need to do something every time one of the balls bounces ( off of the ground, a wall, etc ), like play a sound effect.

You'll want to check out the Havok demos at  \Demo\Demos\Physics\Api\Collide\ContactPointCallbacks\EndOfStepCallback. Overriding the hkpContactListener class will give you the ability to launch a callback every time a rigidbody with that listener equipped experiences a collision.

Here is some code...

// Define our derived class for collision call backs.
class MyEndOfStepListener : public hkReferencedObject, public hkpContactListener
{
public:
 HK_DECLARE_CLASS_ALLOCATOR( HK_MEMORY_CLASS_DEMO );

 void collisionAddedCallback( const hkpCollisionEvent& event )
 {
  registerForEndOfStepContactPointCallbacks( event );
 }

 void collisionRemovedCallback( const hkpCollisionEvent& event )
 {
  unregisterForEndOfStepContactPointCallbacks( event );
 }

 void contactPointCallback( const hkpContactPointEvent& event )
 {
  if ( event.m_contactPointProperties->m_flags & hkContactPointMaterial::CONTACT_IS_NEW )
  {
   if(  hkpContactPointEvent::TYPE_MANIFOLD_AT_END_OF_STEP )
    my_func();
  }
 }
};

// Create the listener.
MyEndOfStepListener* m_listener = new MyEndOfStepListener();

// Create the rigid body
hkpRigidBody* rb = new hkpRigidBody(bodyCinfo);

// Set our listener.
rb->addContactListener( m_listener );

// Clean up when done.
rb->removeContactListener( m_listener );


Now of course you can extend this technique to detecting various kinds of collisions by using this and other collision listener types. Check out the demos, they will give you great ideas.

Sunday, March 25, 2012

3D Bezier Rails

If you'd like to have a 3D "rail" in your application you can use Bezier curves.

Rails are really useful for defining paths for objects to travel across.

Bay-Z-Ay curves can be really simple too for implementing rails. All you need are:

  • A list of 3D points in the order of your path.
  • A function to evaluate the position along this path from time 0 to 1.
Here is an example of a function one could use to get this bezier curve position (written in javascript but it doesn't really matter):


function atT( t: float,
     p0 : Vector3, p1 : Vector3, p2 : Vector3 ) : Vector3 {
        var t2 : float = t * t;
        
        var one_min_t : float = 1 - t;
        var one_min_t_2 : float = one_min_t * one_min_t;
        
        var x : float = one_min_t_2 * p0.x + 
         2 * one_min_t * t * p1.x +
         t2 * p2.x;
        var y : float = one_min_t_2 * p0.y + 
         2 * one_min_t * t * p1.y +
         t2 * p2.y;
        var z : float = one_min_t_2 * p0.z + 
         2 * one_min_t * t * p1.z +
         t2 * p2.z;
        
        return(Vector3(x,y,z));
    }


So given your list of points ( 0, 1, 2, 3, 4, 5, 6... ), you'd break them up into groups of 3 like ( [0,1,2], [2,3,4], [4,5,6]... ). Keep track of which group/segment your on and just interpolate from 0 to 1 to move along it. When you hit 1, increment to the next group/segment and restart at 0.

Saturday, March 24, 2012

C++0x Do It Now

Links:

Hey there. This post is just to spread a bit of awareness about the recent changes to C++ that have been made. Check out those links, no seriously go.

I myself have used the auto keyword for iterators and it is indeed sweet. Normally I'd typedef an iterator declaration but no more! I'll get around to the other stuff eventually but in general it's all intuitive and time saving. Nice stuff.

Friday, March 23, 2012

Havok Tutorial: Content Tools Part 1

What are the Havok Content Tools?

A time will come when you've got stuff working and want to flesh out a stage or something with physical objects like rigid bodies so that you can stand on grounds and smack walls... The Content Tools give you Maya, 3DS Max, and some other things I can remember because I don't use them, plugins that allow you to export entire scenes of physical objects for easy (seriously it's very easy) loading into your program.

I use Maya 2011 Student version, so what I have to say here will be about that.

After you've downloaded and installed the plugin (check out my other tutorials for that), open up Maya and go to WINDOWS>SETTINGS/PREFERENCES>PLUGIN MANAGER. Once there scroll down to hctMayaSceneExport.mll. Select both Auto load and Loaded.

Now on your main tool bar (the one with "File" at the far left) you'll see Havok Content Tools (to the far right probably).

To use this stuff, what you can do is create your geometry as you normally would in Maya, and then convert the meshes you want to into rigid bodies by selecting the mesh and then going to HAVOK CONTENT TOOLS > PHYSICS > CREATE RIGID BODIES. This will turn the selected mesh into a rigid body. A rigid body is a physical object the Havok engine can use to express things like surfaces and collisions with those surfaces.

Once you've created your stage/environment/level/world of rigid bodies you an go to HAVOK CONTENT TOOLS > EXPORT (click the box). Hit the export button and the Havok Content Tools Filter Manager should open up.

This part confused me even after reading the help manual that came with the Content Tools (which you need to read at some point). Basically you need to add the following filters in order to use the scene you've created as a bunch of physical objects in your game...

  • Align Scene To Node
  • Find Mesh Instances
  • Transform Scene
  • Create Rigid Bodies
  • Optimize Shape Hierarchy
  • Preview Tool
Now i'll be the first to tell you that I don't know (or care enough to remember) what some of these filters do. However I know that you need the Preview Tool for sure.

Once you have these filters in your Configuration Set hit Run Configuration. The Preview Tool will open and show you your scene running in real time. Nice.

To actually export what you've created to file (something I couldn't find out how to do anywhere) go to your live preview, FILE > SAVE. Now you can save your scene out in any format you choose to for easy loading into your game. I use HKT.

So that's how you make basic use of the Havok Content Tools Plugin for Maya 2011. I hope this helps out.

Havok Tutorial: Physics API Part 2

It's really important to understand a few things about Havok so that you don't spend hours working on a single error that doesn't really make sense.

The following are some things I've figured out in using Havok myself. I can verify that the described methods work.

  1. Havok needs to run within a single scope.
    • The physics engine initialization/destruction, physics world initialization/destruction, yadda yadda, any calls to Havok need to all take place withing a single block scope. What I mean by this is think of Havok as being another game loop. You can put Havok into the same while(running){} loop as your game or give it it's own thread, but either way it's a running thing that demands everything happen withing one block.
    • You can of course break things up into methods and functions, but they must be called within this loop block. Sub-scopes are also of course fine, just keep it withing the big one.
    • Some things will need to be initialized locally and cannot be declared as a class member. If you have a class member pointer to some havok thing and it gives an access violation error when you initialize it then sorry but you probably need to move the dudette's declaration into the local scope of it's use.
I'll continue to add things here. These "gotcha"s can really slow down development so hopefully you'll be able to absorb whats posted here and avoid the problems yourself.

Update:
So a question I posted on the Intel Havok forums was answered and it's related to the scoping and access violation errors. Here is the response...

"Hi, this looks like a fairly common problem. Here's a another thread with the same issue: http://software.intel.com/en-us/forums/showthread.php?t=80707 (see 3rd post). And the same kind of issue here: http://software.intel.com/en-us/forums/showpost.php?p=178103

The problem is your hkMallocAllocator is going out of scope. Since this is just in your main thread the easiest solution is mentioned in the first post - switch to using 'hkMallocAllocator::m_defaultMallocAllocator' which already exists at a global scope and will not be destructed for the duration of the application.

-Tyler

PS. I'm going to go ahead an change the Havok demos that use the stack allocated hkAllocators in main() to use hkMallocAllocator::m_defaultMallocAllocator instead since it seems to be causing a lot of confusion."