Showing posts with label collidable. Show all posts
Showing posts with label collidable. Show all posts

Saturday, November 12, 2011

Havok: Setting mesh color in the Visual Debugger, Part 2

In part 1 of this series I showed you how to colorize your physics meshes in the Havok Visual Debugger (HVD). However as you may have noticed, this only works for colorizing meshes that are already loaded in the HVD, so if you connect the HVD to the game after those colors have been set you will not see that information. Here's a simple way to get around that problem.

You program is likely directly using an hkVisualDebugger, what you will need to do is derived a new class from hkVisualDebugger. The hkVisualDebugger class has an m_clients variable, but it's access is protected, and there is no accessor to its information in hkVisualDebugger so unless you have the actual source code for Havok, you're going to need to derive your own class from hkVisualDebugger so you can create an accessor to the data that you need.

Create a new header file in your project, name it 'PhysicsVisualDebugger' or whatever class name you would like to use. The code below is the entire class, no .cpp file is needed.

#pragma once

#ifndef __PhysicsVisualDebugger_h_
#define __PhysicsVisualDebugger_h_

#include <common\visualize\hkvisualdebugger.h>

class PhysicsVisualDebugger : public hkVisualDebugger
{
public:
    PhysicsVisualDebugger(const hkArray<hkProcessContext*>,
                          const class hkVtableClassRegistry* classReg = HK_NULL)
         : hkVisualDebugger(contexts, classReg)
    {}

    virtual ~PhysicsVisualDebugger() {};

    unsigned int GetNumClients() const { return m_clients.getSize(); }
};

#endif //__PhysicsVisualDebugger_h_


Make sure any place you were using an 'hkVisualDebugger' that you're not using your new class you've just made.
The goal we're aiming for is to know when somebody connects the HVD to your program. The GetNumClients() above will return to you the number of current clients connected, if you call it at the appropriate time you can compare it to check if that number has just increased.

In my example below, 'm_pDebugger' is a pointer to a 'PhysicsVisualDebugger'. Put this code wherever you're currently stepping the HVD.

unsigned int numConnections = m_pDebugger->GetNumClients();

// Update the debuggers (which also checks for new clients)
m_pDebugger->step(m_fStepLength);

// If there are now more connections than before the update
if ( m_pDebugger->GetNumClients() > numConnections )
{
    // This is where you will want to go through all physics
    // objects and have to re-send their color info to the
    // debugger.
    UpdateDebuggerInfoForAllEntities();
}

Notice we query the number of connections before stepping the debugger, store that number, and then after stepping the debugger we query for number of connections again. If the number of clients has increased, then you should find a way of having all of your objects resend their color information to the HVD. In my case whenever I add an object to the Havok world, I keep track of its pointer in a list so I can call a function on everything in that list at any time to have them refresh their information for the HVD.

Sunday, November 6, 2011

Havok: Setting mesh color in the Visual Debugger, Part 1

Anyone developing a game using Havok no doubt knows about the Havok visual debugger (which I'll refer to as the HVD), however if you're using the free SDK there is little provided information on how to send data to the visual debugger. Having worked with the full Havok source on a previous project I can provide what I hope to be some valuable insight on how to better utilize the HVD, which should help you debug your game easier.

Setting colors is the HVD is actually really simple, Havok provides a macro that does the work for you, you only have to pass a byte-packed unsigned 32-bit integer representing the color you want, and the pointer to the hkpCollidable. The format of your integer is 1 byte per channel, first byte is the alpha-channel, then red, blue, and green.

Here's a simple function that does the dirty work for you:

// Needed for calling color change macro
#include <common\visualize\hkdebugdisplay.h>

// You'll of course need any other headers for any other physics stuff 
// you're doing in your file

void SetColorForPhysicsDebugger( unsigned int Red, unsigned int Green,
                                 unsigned int Blue, unsigned int Alpha, 
                                 const hkpCollidable* pCollidable )
{
    // Havok takes an unsigned int (32-bit), allowing 8-bits for 
    // each channel (alpha, red, green, and blue, in that
    // order).

    // Because we only need 8-bits from each of the 32-bit ints 
    // passed into this function, we'll mask the first 24-bits.
    Red &= 0x000000FF;
    Green &= 0x000000FF;
    Blue &= 0x000000FF;
    Alpha &= 0x000000FF;

    // Now we pack the four channels into a single int
    const uint32_t color = (Alpha << 24) | (Red << 16) | (Green << 8) | Blue;

    // We use the macro provided by Havok
    HK_SET_OBJECT_COLOR( reinterpret_cast<hkulong>( pCollidable ), color );
}

In the image below you can see this in action. I have a running sample in which rigid bodies are red and opaque by default, whereas phantoms/triggers are blue and translucent.


Using colors for different categories of objects in your game can be extremely powerful. On one project I was on I created an entire custom interface and tool around filtering physics to show developers only what they were looking for, for example NPCs could collide with certain triggers that human players could not, so there was a filter for looking at the physics world from an NPCs point of view, while in the filter you could only see physics that the NPC could collide with.

This is part 1 of 2 of this series, part 2 shows you how to know when somebody connects to the HVD, because you'll need to resend all color information anytime someone connects.