[Noob Question]Tutorials for Integrating Havok with 3rd party graphics engine

[Noob Question]Tutorials for Integrating Havok with 3rd party graphics engine

imagem de gonx

Hi,

Would there be any recommended tutorials and approach for integrating havok to open source graphics engines? I've been studying the docs and sample sources(havok demo framework) but am still looking for a way. I was wondering if anyone can point a noob in the right direction.

47 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Hey,

I did the same question some posts ago, check this out:
http://software.intel.com/en-us/forums//topic/59553

I tried to use OGRE 3D (alone, without Havok), but I found it a little bit complex for a beginner.
So I changed to Irrlicht, what is a lot more easy.

My game project is still in its first steps, but soon I will be integrating Havok with Irrlicht.

Which graphic engine will you use? Maybe we could share some ideas.

imagem de gonx

Hi spill,

Your question was the first one i read when i got to the forums. Glad to hear you've found Irrlicht as a good starting point for your game project.

I plan on using Ogre 3d as my graphic engine and am still in the early stages of studying Havok from the SDK examples. But Ogre because from the forums one can "extend" the basic graphic engine functionalities to make it into a game engine and i'd like to try this one out.

For the record i plan on taking an Ogre demo example then try integrating it with Havok via SDK. I most probably have to backtrack and study the Havok examples again and figure out how havok does it quoting from havokdaniel in your post:

"..you can tell Havok to simulate some of your objects, and then get the
new locations/orientations of those objects from the Havok SDK, and
transform your graphical objects to those new values...
"

So i think the way to go about my project is to understand how Havok can get the values from a graphic object from a graphics engine. Compute physics then give back the results to the graphics engine. I could be wrong but i'm giving it a shot.

How's your project going so far? I think far better than my efforts hehe.

Hi gonx,

How are you planning on making your Ogre levels/objects? If you're using 3DS Max, Maya or XSI you can use the Havok Content Tools right in there to export your geometry as physics objects. This will basically give you an HKX file, which describes your scene in a format understandable by the Havok SDK.

When you load up your graphics from file (maybe a .mesh file if it's Ogre you're using), you load up your HKX too into Havok, and start simulating the physics while rendering your graphics. Every frame you're going to need to do that update then, changing the positions of your rendered objects according to the transforms you get from Havok.

Hope this helps you figure out exactly what you need to do to get things going. Can't wait to see what you guys come out with!

Daniel

imagem de havokchris

Just another thought - you might be able to get some ideas on general physics/graphics integration from OgreBullet, an integration package for Ogre and Bullet (another free physics engine). I've never used either so I can't vouch for them (nor OgreBullet), but I believe the Bullet API is similar to Havok's, so it might be easy to apply concepts from one to the other.

-Chris

gonx:
How's your project going so far? I think far better than my efforts hehe.

Hey Gonx, I am still studying the graphics engine, so I haven't got anything big yet.

Very interesting your aproach to test Havok in a Ogre example.
However, I will improve my knowledge with Irrlicht before playing with Havok.

While, I decide about other libraries to use in my project (AI, sound, user input, etc...).
Probaby I will use OIS for user interface, irrKlang for sound and develop the AI from the beginning.

Any better sugestion?

imagem de gonx
spill:
While, I decide about other libraries to use in my project (AI, sound, user input, etc...).
Probaby I will use OIS for user interface, irrKlang for sound and develop the AI from the beginning.

Any better sugestion?

I think you're good to go. I highly recommend going to www.aigamedev.net for your AI needs. I'll be posting again after i figure out the integration of Renderer and Havok engine.

havokdaniel:
How are you planning on making your Ogre levels/objects? If you're using 3DS Max, Maya or XSI you can use the Havok Content Tools right in there to export your geometry as physics objects. This will basically give you an HKX file, which describes your scene in a format understandable by the Havok SDK.

Yes, am currently generating some HKX files with Maya right now. Still studying the docs.

havokdaniel:
When you load up your graphics from file (maybe a .mesh file if it's
Ogre you're using), you load up your HKX too into Havok, and start
simulating the physics while rendering your graphics. Every frame
you're going to need to do that update then, changing the positions of
your rendered objects according to the transforms you get from Havok.

I think this is the part i really need to study on. I'll get on it right away.

havokchris:
Just another thought - you might be able to get some ideas on general physics/graphics integration from OgreBullet, an integration package for Ogre and Bullet (another free physics engine).

Just downloaded it now. I'll be checking this too.

thanks for the inputs! This will help me start off with the right foot. Hope to be posting again soon after this one.

imagem de gonx

Found this blog on Ogre & Havok.

http://www.daksystems.net/blog/index.php?entry=entry080702-084457

Cant wait to try it out.

Sorry to necro-post but I was curious if you had any luck with this blog post you mention. The author doesn't seem to go in to much detail and the code isn't exactly commented well.

Ok I understand that most people use Ogre 3D as Graphic engine but what about people who use 3D Max Studio. Are there any tutorial on using 3D Max Studio with Havok then exporting them into your Game with all Physics and Logic. I would really appreciate if there was tutorial about Havok With C++ and 3D Max. Been searching for hours for some kind of tutorial about Havok but could not find any. Please help me

Hi bingobeawr,

There are Havok tools which export physics data from 3DS Max to a format loadable by the Havok runtime, but getting Havok to work with your graphics engine depends on the engine. What sort of graphics engine are you (planning on) working with? If not Ogre, are you using your own graphics engine? Irrlicht?

Daniel

can you fill me in on these Graphic Engines. From what I understand they compile and render like 3D Max. How about OpenGL or DirectX. So you cant use Havok or 3D Max as Graphic Engine. Then What should I use.

Hi bingobeawr,

A game engine is made up of a lot of different components. Graphics, Animation, Audio, Physics, AI and Controller Input are a few of those. They're all tied together and all use each other to make the final product. The line between them isn't always clear but in general it's broken up something like that.

Havok provides the Physics and Animation parts of that whole system. The rest of it has to be provided by other software. Ogre3D can handle graphics and something like OIS can handle controller input. Or you could try something like SDL which can handle video/audio/controller input for you. Or you could write it all yourself.

3D modellers, such as 3DS Max, Maya, XSI, and Blender, are tools which are used to generate graphical (and/or physical and animation) content for games. In these tools you create your characters and environments and save them out. Your game engine then loads these up when it starts and allows the player interact. These tools cannot be called game engines or graphics engines in this context. Rather, they are game/graphics design and creation tools.

Any of this software which draws 3D graphics to your screen, be it a graphics engine being used in a game, or be it 3DS Max, uses DirectX or OpenGL to access your graphics hardware. If you were to write your own graphics engine you'd probably end up using DirectX or OpenGL a lot, but the likes of Ogre3D or Irrlicht or SDL look after this for you with simplified interfaces.

I hope my explanation isn't too confusing. If you need advice on what engine to use feel free to ask around on the forums here. Some guys are doing great work integrating with different engines.

Thanks,
Daniel

Hi Bingobeawr:

We have a request regarding your Avatar use - sorry to ask this - but we wondered if you could use something other than the Havok logo (or a modified version if you choose).. just so its easy and clear for folks to see who the Havok moderators are, vs. public users.

This is just to make it easier for us to keep track of who is responding (or not) from Havok, when critical issues come up.

Very sorry to ask, but we think it would help things a bit on our end.

Regards,

Jeff

No problem I canceled my avatar. I was just testing if the avatar works.

havokdaniel:Hi bingobeawr,

A game engine is made up of a lot of different components. Graphics, Animation, Audio, Physics, AI and Controller Input are a few of those. They're all tied together and all use each other to make the final product. The line between them isn't always clear but in general it's broken up something like that.

Havok provides the Physics and Animation parts of that whole system. The rest of it has to be provided by other software. Ogre3D can handle graphics and something like OIS can handle controller input. Or you could try something like SDL which can handle video/audio/controller input for you. Or you could write it all yourself.

3D modellers, such as 3DS Max, Maya, XSI, and Blender, are tools which are used to generate graphical (and/or physical and animation) content for games. In these tools you create your characters and environments and save them out. Your game engine then loads these up when it starts and allows the player interact. These tools cannot be called game engines or graphics engines in this context. Rather, they are game/graphics design and creation tools.

Any of this software which draws 3D graphics to your screen, be it a graphics engine being used in a game, or be it 3DS Max, uses DirectX or OpenGL to access your graphics hardware. If you were to write your own graphics engine you'd probably end up using DirectX or OpenGL a lot, but the likes of Ogre3D or Irrlicht or SDL look after this for you with simplified interfaces.

I hope my explanation isn't too confusing. If you need advice on what engine to use feel free to ask around on the forums here. Some guys are doing great work integrating with different engines.

Thanks,
Daniel

Thanks for taking your time.

Ok, but what tools do you use to connect all of those things and enable them to work directly with each other.

yatesjdy:

Hi Bingobeawr:

We have a request regarding your Avatar use - sorry to ask this - but we wondered if you could use something other than the Havok logo (or a modified version if you choose).. just so its easy and clear for folks to see who the Havok moderators are, vs. public users.

This is just to make it easier for us to keep track of who is responding (or not) from Havok, when critical issues come up.

Very sorry to ask, but we think it would help things a bit on our end.

Regards,

Jeff

Sorry about my avatar I disabled it. It seems that avatars function is availeble only for one avatar and its the "Havok Logo" all other avatar with exlacly same size and type seem not to upload and show. I wonder how to upload any different kind of avatar.

Hi bingobeawr,

You use C++ to put them all together and get them to work :-)

Daniel

Do anyone use Unreal Engine 2. As a Graphic Engine .

Ican provide a link to download it if anybody need to.

Sergey.

Weird, I came across this post while Googling for websites that cracked
my capcha and were posting links to my comment sections. I'm the
author of that tutorial listed above.... sorry. The intent was never
to provide a Havok/Ogre wrapper. I was testing the functionality for a
project at work and thought it would be fun to post my thoughts,
especially since no one else seemed to have done so.

The code has been modified since the initial post to include character controllers, a scene loader, and some other basic functionality. It also uses Havok's helpful little GameUtils file to load in unorganized geometry from .tk files.

Actually that leads to a question I've had: Is there any reason I shouldn't be using the loadTK2MOPP? Is there a more efficient method of loading in level data for physics? I've not noticed any real slow-down but I'm also using some pretty small(memory-wise) meshes. Second question: In my post I provide a link to my source code which included the GameUtils.cpp file. Is this a problem? Havok isn't truly open content so I didn't know if I could host this file. If it's a problem please let me know so I can take it down.

bingobeawr, doesn't unreal engine 2 use it's own physics engine, Karma? If you want an idea on how to link the components together you may want to take a look at Ogre's source code or even mine. For basic collision detection all you really need is to define a sphere or cube inside Havok and then update your object with the direction and position of the havok object. That's an oversimplification I know. I'm just so greatful that Havok chose to invest some time creating a multitude of demos. Pretty much every question I've had has been answered in those or the main pdf.

No I think the one that I got is only Graohic Engine. Also I found an awesome AI system which was used in F.E.A.R. from what I know it was in Top 10 AI engines and got second place after Black and White.

Here is the link http://aigamedev.com/source/fear-sdk

If you search a bit in there you will fund a tutorial on how to extract AI engine form the game(source code).

imagem de gonx

Hi,

It's been a while since i've posted on the thread as I was busy at work. Glad to hear valuable inputs from you guys out there. Yes I do understand by the way that Ominae392's project is not an Ogre/Havok wrapper API and regularly I have been searching just in case some project actually makes one. But the blog Ominae392 made was by far the best one I've seen that integrates ogre and havok. Thanks again Ominae392 I been studying the example you made

Unfortunately due to my busy schedule i wasn't able to come up anything yet with the example from Ominae392. I've only just managed to build the project and am struggling with some Ogre concepts like loading meshes,etc. because so far I can't seem to load meshes using the program. I'm probably missing some resource paths on my ogre config file.. again this will take me a while as I'm still new to Ogre.

@Ominae392 - In the code what's the relationship between cube.mesh and the level.tk file in the example you provided? As i understand it.. Can I clarify on which of the following is the correct implementation of what u did?

1. let's say i have a 3d model in blender.. then i get a cube.mesh file when i used the ogre blender exporter.. does this mean i have to have a level.tk file taken somehow from the cube.mesh ?

2. Or it should be that i take level.tk from havok sdk example.. somehow view it with blender(change the content of level.tk so it becomes viewable in blender) to get the Cube.mesh file to load with Ogre

"1. let's say i have a 3d model in blender.. then i get a cube.mesh file
when i used the ogre blender exporter.. does this mean i have to have a
level.tk file taken somehow from the cube.mesh ?"

Ack, sorry for the lack of comments. Ignore cube.mesh and level.tk. They aren't related. Take a look at: HKPrimitive.cpp (it's been uploaded to the server refenced in this post.)

Here is what I did: There are 3 types of physical objects in my example: cubes, spheres, and level geometry (.tk files). Level geometry (.tk files) are used to define complex structures that don't fit neatly inside of a cube or sphere. Like a mountain range. If you put a cube around that your player won't move along the jagged peaks, they'll just hit the flat cube surface.

So lets say you make a crate in blender. The crate is a nice cube shape, there is no need to create a .tk file from this mesh. What you'd do is export the mesh from blender, open it in ogre, and then create a Havok cube that corresponds to your crate. Well actually its more of a box shape. The tricky part is getting the scaling to work. When you create a .tk file there isn't a problem because that is created directly from the mesh. Right now I've got those values hardcoded because I built my sphere and crate to unit scale meaning I know their x/y bounds are 0-1. What you should do instead is load the crate in ogre and then find that meshes bounding box. Then use that bounding box to create your Havok box shape.

Now lets say you want to create some funky shapes like a mountain range. You can't really encompass this easily with a cube or sphere. This is where the .tk file comes in. You only need to create these for complex geometries. And honestly I don't know if this is the best way to do things, it just made sense in my head at the time. In this case you export the model from Blender in 2 formats, .mesh.xml for Ogre and .obj for Havok. Using the obj2tk function you can create the corresponding .tk file for your mountain range.

Does that make any sense?

The newest code changed a little bit. I don't know if you noticed but the level.tk that comes with the Havok examples is laying on its side. So "up" is not towards the y-axis. This also requires the CharacterController in Havok's examples to create a custom "up" vector that points along the z-axis instead. It's a bit confusing. After learning their example I reoriented the level and modified their example to work in a way I'm used to, with up being towards positive y.

I'll try and post an objt2tk script tonight to help convert some of the examples.

Hi Ominae392,

Can you please cease distribution of GameUtils.cpp and anything else that you got from the zip file you downloaded? Redistributing any of that content is in violation of the terms to which you agreed when originally downloading the distribution. Please do not make these available to anyone beyond directing them to havok.com/tryhavok.

Regarding the TK question: .tk files may soon disappear from Havok releases as theses files have been deprecated by .hkx files. Instead of .tk files and loadTK2MOPP, serialized hkpExtendedMeshShapes loaded by an hkLoader is the recommended approach.

Thanks,
Daniel

havokdaniel:Hi Ominae392,
Can you please cease distribution of GameUtils.cpp and anything else that you got from the zip file you downloaded? Redistributing any of that content is in violation of the terms to which you agreed when originally downloading the distribution. Please do not make these available to anyone beyond directing them to havok.com/tryhavok.

Alrighty. All of my example code has been pulled until I can get home and upload a clean set of source code. I'll have the examples back up by this evening.

havokdaniel:
Regarding the TK question: .tk files may soon disappear from Havok releases as theses files have been deprecated by .hkx files. Instead of .tk files and loadTK2MOPP, serialized hkpExtendedMeshShapes loaded by an hkLoader is the recommended approach.

Can you point me to an example app? Any particular reason for the deprecation, is the new method faster/ more efficient?

Hi Ominae392,

Thanks for removing that!

The reason why .hkx files are much faster is that they can be saved as platform-specific binary files and then loaded straight into memory. No parsing of vertices or construction of geometry is necessary, just a memcpy().

hkLoader is used in most of the animation demos but not many of the physics demos, as most of the geometry for the physics demos is loaded at runtime. However, hkBinaryPackfileReader (which is used by hkLoader) is used in a few that you can see. Have a look at Physics/UseCase/AssetStreaming and PhysicsApiCollideShapesLandscapeChunkMopp. A pretty simple one which loads a .hkx into a buffer is here: CommonApiSerializeNativePackfileLoadNativePackfileLoadDemo.cpp.

Let me know if you have any questions about hkLoader or hkBinaryPackfileReader.

Daniel

Alright I'll give that a shot.

My old source code is back up at www.daystems.net/svn/public/HavokTest1 Minus the Havok licensed stuff.

Login: Guest
pass: guest

I want to know which is the best free and open source Gpaphics Engine. From what I looked up..

Ogre 3D--No way, no quality

Irrlichit--Better but could be improved.

UnrealEngine 2Level Editor-AWESOME but cant do much without license. Even the tutorial are for liceners only who have their personalized logins.

So what should I choose or do you know any other good Graphic Engine.

Can you export a 3D Level from 3D Max to Irrlichit Editor?

Thank You

havokdaniel, I've seen a few older posts regarding the hkx file format. Is there any API for creating hkx files from c++? I'm not a modeller but I do know how to handle 3D data and I'd like to be able to convert from .obj, ply, and a few other formats without having to get a Maya or 3DS. If that's the only route then so be it.

Hi Ominae392,

.hkx files are just serialized Havok objects. If you can get anything loaded into Havok then you can create a .hkx file with the hkBinaryPackfileWriter or hkXmlPackfileWriter.

There are a couple of options for taking geometry in some arbitrary format into Havok. Here are a few I can think of:

  • Load it up in Max/Maya/XSI and use the respective scene exporter with the filter manager to export to .hkx.
  • Load it up in some other modeler (like Blender) and write your own scene exporter (which would still use the same filter manager) to export to .hkx.
  • Parse the geometry file and output an XML .hkx. This would require a little reverse-engineering on your part but I don't think it's impossible to do.
  • Parse the geometry file and use that data to create Havok objects in the Havok runtime. Then serialize out this code using the hkPackfileWriter.

That last one seems like the easiest if you don't want to use one of the supported modelers.

Thanks,
Daniel

imagem de havokchris
havokdaniel:The reason why .hkx files are much faster is that they can be saved as platform-specific binary files and then loaded straight into memory. No parsing of vertices or construction of geometry is necessary, just a memcpy().

The other nice thing is that you can compute the MOPP (collision bounding volume structure) offline, instead of every time you load your level. Building the MOPP may be fast for a small mesh, but it definitely starts to slow down as the size increases. Anything that decreases level load time is a Good Thing, both for the people playing the game, and for you when you're trying to debug something.

Last but not least, the binary .hkx files should be smaller than the .tk files, since it doesn't store the floating point values as string.

-Chris

I can vouch for that. The binary .hkx files are much smaller and load much, much faster. Even relatively large MOPP scenes load pretty fast.

Hi Chris!

imagem de gonx

Hi,

It's been a while since my last post. So far i've been making some progress in understanding the API .

What i did was study the standAloneDemos included in the havok download.

Currently i've had success in loading some .hkx files based from the .chm manual included in the havok engine download. Managed to advance the timestep and viewed the simulation in the visualdebugger . Problem is how can i update my 3rd party graphics objects from the API ..

Some questions though maybe someone has had similar problems.

In the code:

...
physicsWorld->resetThreadTokens();
multithreadingUtil->startStepWorld( timestep );
multithreadingUtil->waitForStepWorldFinished();
...

Where the physics world has advanced a timestep. How can i get the updated positions of my rigid bodies ? Would there be a data structure that is being returned from hkpWorld that i can use to update may 3rd party graphics object?

Hi gonx,

Have a look at this thread and see if it answers any of your questions:
http://software.intel.com/en-us/forums//topic/59714

Daniel

imagem de gonx

Hi Guys,

So far i've been successful in getting rigid body data from the hkx in addition to loading it in the ogre graphics engine. Right now i've been having problems in trying to step the simulation.

In the code below:

class HavokProgram {

hkpWorld *physicsWorld;

hkpMultiThreadUtil *multithreadingUtil;

public void initHavok() { }

}

============

class OgreProgram {

void OgreProgram::step() {

HavokProgram *havok;

...

havok->physicsWorld->resetThreadTokens();
havok->multithreadingUtil->startStepWorld( timestep );
havok->multithreadingUtil->waitForStepWorldFinished();

...
}

}

I've traced my program and it seems thatit crashes when reaching the waitForStepWorldFinished() part of the program.

In the pseudocode above this was the part where im tryingtoadvance the simulation step. A couple of questions I've thought of so i can get back on track.

1. I've read in some of the forums here

(http://software.intel.com/en-us/forums//topic/59300)

("basically i found that the havok step delta needs to be called from the same thread where havok was initialized ..")

that the stepping of the simulation should be executed on the same thread where havok was initialized? Would this be the reason why waitForStepWorldFinished() is crashing?

2.I've also readfrom these forums that there is this callstack one can use to debug.How does one print the callstack?

Thanks.

imagem de sean.thurston

Hi gonx,

Can I see how you are setting up memory and and the multithreading util? There is an example of doing multithreaded simulation in the ConsoleExampleMt. Also make sure to check the docs Havok Physics->Multithreading and specifically the section called Running Physics Multithreaded.

If you are using Visual Studio, the call stack is typically in the lower right had window. It is tabbed along with Breakpoints and Output. When you crash it is typically brought to the front. You can just grab the information there.

I hope this helps.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com

[deleted by request of the author]

imagem de gonx

sean.thurston:Hi gonx,

Can I see how you are setting up memory and and the multithreading util? There is an example of doing multithreaded simulation in the ConsoleExampleMt. Also make sure to check the docs Havok Physics->Multithreading and specifically the section called Running Physics Multithreaded.

If you are using Visual Studio, the call stack is typically in the lower right had window. It is tabbed along with Breakpoints and Output. When you crash it is typically brought to the front. You can just grab the information there.

I hope this helps.

Thanks,
Sean

Hi Sean,

Thanks for the reply. Sorry for the late reply as i have been reading the other posts and comparing my code to the examples of the SDK in trying to solve this problem. Pasting some of my code below. Hope it turns out ok.

I'm currently loading an hkx file to setup the world. It's just like the one in ConsoleExampleMt by replacing the part below:

{

// The world cinfo contains global simulation parameters, including gravity, solver settings etc.

hkpWorldCinfo worldInfo;

// Set the simulation type of the world to multi-threaded.worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

physicsWorld = new hkpWorld(worldInfo);

}

===============================

Here is the method where i try to call the stepping.

void HavokPhysics::initHavok(std::vector *tempbodies) {

// Initialize the base system including our memory system

hkPoolMemory* memoryManager = new hkPoolMemory();

threadMemory = new hkThreadMemory(memoryManager, 16);

hkBaseSystem::init( memoryManager, threadMemory, errorReport );

memoryManager->removeReference();

// We now initialize the stack area to 100k (fast temporary memory to be used by the engine).

//char* stackBuffer;

{

int stackSize = 0x100000;

stackBuffer = hkAllocate( stackSize, HK_MEMORY_CLASS_BASE);

hkThreadMemory::getInstance().setStackArea( stackBuffer, stackSize);

}

{

// Create the physics world

//hkpWorld* physicsWorld;

/*

{

// The world cinfo contains global simulation parameters, including gravity, solver settings etc.

hkpWorldCinfo worldInfo;

// Set the simulation type of the world to multi-threaded.

worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

physicsWorld = new hkpWorld(worldInfo);

}

*/

// Open the file

hkIstream infile( "test_Default.hkx" );

if(infile.isOk()){

WriteToLog("infile is OK!!
");

}

// Load the file into a binary packfile reader. Use a hkXmlP
ackfileReader here if your data is XML.

hkBinaryPackfileReader packfileReader;

packfileReader.loadEntireFile( infile.getStreamReader() );

// Version contents

hkVersionUtil::updateToCurrentVersion( packfileReader, hkVersionRegistry::getInstance() );

// Get the contents of the binary packfile.

packfileContents = static_cast(packfileReader.getContents( hkRootLevelContainerClass.getName() ));

// Store a reference to the physics data in the packfile contents container

physicsData = static_cast(packfileContents->findObjectByType( hkpPhysicsDataClass.getName() ));

(*physicsData->getWorldCinfo()).m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

// Create a world and add the physics systems to it

physicsWorld = new hkpWorld( *physicsData->getWorldCinfo() );

//

// Pre-allocate some larger memory blocks. These are used by the physics system when in multithreaded mode

// The amount and size of these depends on your physics usage. Larger simulation islands will use larger memory blocks.

//

{

hkMemory::getInstance().preAllocateRuntimeBlock(512000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(256000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(128000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(64000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(32000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);

hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);

}

//

// When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks

// to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread

// must call markForRead / markForWrite before it modifies the world to enable these checks.

//

physicsWorld->markForWrite();

//

// Register all collision agents, even though only box - box will be used in this particular example.

// It's important to register collision agents before adding any entities to the world.

//

{

hkpAgentRegisterUtil::registerAllAgents( physicsWorld->getCollisionDispatcher() );

}

//

// Create a multi-threading utility. This utility will create a number of threads that will run the

// physics step i
n parallel. The main thread calls functions in the utility which signal these threads

// to start a new step, or wait for step completion.

//

hkpMultithreadingUtilCinfo info;

// Add all the physics systems to the world

for ( int i = 0; i < physicsData->getPhysicsSystems().getSize(); ++i )

{

physicsWorld->addPhysicsSystem( physicsData->getPhysicsSystems()[i] );

}

info.m_world = physicsWorld;

info.m_numThreads = NUM_THREADS;

// In this example we enable timers. The multi-threading util will allocate a buffer per thread for capturing timer data.

// If you leave this flag to false, no timers will be enabled.

info.m_enableTimers = true;

multithreadingUtil = new hkpMultithreadingUtil(info);

// Create all the physics rigid bodies

//setupPhysics( physicsWorld );

//

// Initialize the visual debugger so we can connect remotely to the simulation

// The context must exist beyond the use of the VDB instance, and you can make

// whatever contexts you like for your own viewer types.

//

context = new hkpPhysicsContext();

hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers

context->addWorld(physicsWorld); // add the physics world so the viewers can see it

hkVisualDebugger* vdb = setupVisualDebugger(context);

context->m_monitorStreamBegins.setSize(NUM_THREADS);

context->m_monitorStreamEnds.setSize(NUM_THREADS);

// Now we have finished modifying the world, release our write marker.

physicsWorld->unmarkForWrite();

for(int i = 0; i < physicsData->getPhysicsSystems().getSize(); i++) {

hkpPhysicsSystem *const ps = physicsData->getPhysicsSystems()[i];

for(int j=0; jgetRigidBodies().getSize();j++) {

hkpRigidBody *const rb = ps->getRigidBodies()[j] ;

hkpRigidBody *cloney = rb->clone();

tempbodies->push_back(cloney);

}

}

}

========================================

On a different class i do the stepping. I'm using Ogre for this one. This is the part where im getting my errors

bool OgreFrameListener::frameStarted(const FrameEvent &evt)

{

bool started = ExampleFrameListener::frameStarted(evt);

stepping();

return started;

}

void OgreFrameListener::stepping() {

havok->getWorld()->resetThreadTokens();

// This will signal all threads which are in the wait state, to start processing stepDeltaTime() concurrently.

havok->getMultithreadingUtil()->startStepWorld( 1.0f/60.0f );

havok->getMultithreadingUtil()->waitForStepWorldFinished(); <==================== Program crashes here.

std::vector rigidbodies = this->bodies;

// Pause until the actual time has passed

while (stopWatch.getElapsedSeconds() < lastTime + timestep);

lastTime += timestep;

}

Thanks again for the quick reply. I'm currently looking into this problem by looking at the examples from the sdk and looking at the forums on the "stepping".

Regards,

gonx

imagem de sean.thurston

Hi gonx,

You shouldn't have to update the world in the same thread that the world is initialized in. Can you make sure to compile in full debug mode and can you give a callstack of the crash. Debug mode will turn on all the asserts and we can make sure that everything happening is thread-safe.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
imagem de gonx

sean.thurston:Hi gonx,

You shouldn't have to update the world in the same thread that the world is initialized in. Can you make sure to compile in full debug mode and can you give a callstack of the crash. Debug mode will turn on all the asserts and we can make sure that everything happening is thread-safe.

Thanks,
Sean

Hi sean,

Thanks for the quick response. Below is a callstacki'm getting in debug mode. I also see some accessCheck() methods in the stack.

testy.exe!hkMultiThreadCheck::accessCheck(hkMultiThreadCheck::AccessType type=HK_ACCESS_RO) Line 186 + 0x6f bytes C++
testy.exe!hkMultiThreadCheck::accessCheckWithParent(const hkMultiThreadCheck * parentLock=0x03b2bd98, hkMultiThreadCheck::AccessType parentType=HK_ACCESS_IGNORE, const hkMultiThreadCheck & lock={...}, hkMultiThreadCheck::AccessType type=HK_ACCESS_RO) Line 245 + 0xd bytes C++
testy.exe!hkpRigidBody::getCinfo(hkpRigidBodyCinfo & info={...}) Line 318 C++
testy.exe!hkpRigidBody::clone() Line 390 C++
> testy.exe!HavokPhysics::initHavok(std::vector > * tempbodies=[0]()) Line 251 + 0x15 bytes C++
testy.exe!OgreFrameListener::OgreFrameListener(Ogre::RenderWindow * win=0x0144fcc8, Ogre::Camera * cam=0x014a6140, Ogre::SceneManager * sceneMgr=0x0149c630) Line 26 C++
testy.exe!TutorialApplication::createFrameListener() Line 193 + 0x43 bytes C++
testy.exe!ExampleApplication::setup() Line 140 + 0xf bytes C++
testy.exe!ExampleApplication::go() Line 89 + 0xf bytes C++
testy.exe!WinMain(HINSTANCE__ * hInst=0x00400000, HINSTANCE__ * __formal=0x00000000, char * strCmdLine=0x00161f01, HINSTANCE__ * __formal=0x00000000) Line 218 + 0x8 bytes C++
testy.exe!__tmainCRTStartup() Line 574 + 0x35 bytes C
testy.exe!WinMainCRTStartup() Line 399 C
kernel32.dll!7c816ff7()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]

I'll be looking more into this again later this evening.

Thanks again!

imagem de sean.thurston

Hi gonx,

Try moving your unmarkForWrite() method call to after your cloning code. See if that helps.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
imagem de gonx
sean.thurston:Hi gonx,

Try moving your unmarkForWrite() method call to after your cloning code. See if that helps.

Thanks,
Sean

Hi sean,

Many thanks for your informative and timely response. It definitely did helped the problem. . But now I'm encountering some other stack traces which i am unable to find the cause. The debugger currently breaks at a '}' so i am unable to figure out the exact problem. The stack trace and source code to my initHavok method are included below:

I have some thoughts on this but just want to ask again with the stack trace below so i can identify the source of the error.

1. Does the stack below indicate that I have to again use a markForWrite/unmarkForWrite to some hkpRigidBody that havok can't seem to destroy?

2. Or i forgot to do a ->removeReference somewhere?

=========
Stack
=========
> testy.exe!hkMultiThreadCheck::accessCheck(hkMultiThreadCheck::AccessType type=HK_ACCESS_RW) Line 177 + 0x67 bytes C++
testy.exe!hkMultiThreadCheck::accessCheckWithParent(const hkMultiThreadCheck * parentLock=0x03b2bd98, hkMultiThreadCheck::AccessType parentType=HK_ACCESS_IGNORE, const hkMultiThreadCheck & lock={...}, hkMultiThreadCheck::AccessType type=HK_ACCESS_RW) Line 245 + 0xd bytes C++
testy.exe!hkpRigidBody::~hkpRigidBody() Line 309 + 0x24 bytes C++
testy.exe!hkpRigidBody::`scalar deleting destructor'() + 0x8 bytes C++
testy.exe!cleanupLoadedObjecthkpRigidBody(void * p=0x03b55fd0) Line 22 + 0xc bytes C++
testy.exe!hkPackfileData::callDestructors() Line 33 + 0x39 bytes C++
testy.exe!hkPackfileData::~hkPackfileData() Line 44 C++
testy.exe!hkBinaryPackfileReader::BinaryPackfileData::`scalar deleting destructor'() + 0x8 bytes C++
testy.exe!hkBinaryPackfileReader::~hkBinaryPackfileReader() Line 339 C++
testy.exe!HavokPhysics::initHavok(std::vector > * tempbodies=[0x00000002](0x03b2a100,0x03b29f00)) Line 355 + 0xf bytes C++
testy.exe!OgreFrameListener::OgreFrameListener(Ogre::RenderWindow * win=0x0144fcc8, Ogre::Camera * cam=0x014a6140, Ogre::SceneManager * sceneMgr=0x0149c630) Line 26 C++
testy.exe!TutorialApplication::createFrameListener() Line 193 + 0x43 bytes C++
testy.exe!ExampleApplication::setup() Line 140 + 0xf bytes C++
testy.exe!ExampleApplication::go() Line 89 + 0xf bytes C++
testy.exe!WinMain(HINSTANCE__ * hInst=0x00400000, HINSTANCE__ * __formal=0x00000000, char * strCmdLine=0x00161f01, HINSTANCE__
* __formal=0x00000000) Line 218 + 0x8 bytes C++
testy.exe!__tmainCRTStartup() Line 574 + 0x35 bytes C
testy.exe!WinMainCRTStartup() Line 399 C
kernel32.dll!7c816ff7()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
testy.exe!hkpLinearParametricCurve::getBinormal(float t=-2.3555805e-038, hkVector4 & up={...}) Line 314 + 0x82 bytes C++

=============
Source
=============

void HavokPhysics::initHavok(std::vector *tempbodies) {

// Initialize the base system including our memory system
hkPoolMemory* memoryManager = new hkPoolMemory();
threadMemory = new hkThreadMemory(memoryManager, 16);
hkBaseSystem::init( memoryManager, threadMemory, errorReport );
memoryManager->removeReference();

// We now initialize the stack area to 100k (fast temporary memory to be used by the engine).
//char* stackBuffer;
{
int stackSize = 0x100000;
stackBuffer = hkAllocate( stackSize, HK_MEMORY_CLASS_BASE);
hkThreadMemory::getInstance().setStackArea( stackBuffer, stackSize);
}

{

// Create the physics world
//hkpWorld* physicsWorld;
/*
{
// The world cinfo contains global simulation parameters, including gravity, solver settings etc.
hkpWorldCinfo worldInfo;

// Set the simulation type of the world to multi-threaded.
worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

physicsWorld = new hkpWorld(worldInfo);
}
*/
// Open the file
hkIstream infile( "test_Default.hkx" );
if(infile.isOk()){
WriteToLog("infile is OK!!
");
}
// Load the file into a binary packfile reader. Use a hkXmlPackfileReader here if your data is XML.
hkBinaryPackfileReader packfileReader;
packfileReader.loadEntireFile( infile.getStreamReader() );

// Version contents
hkVersionUtil::updateToCurrentVersion( packfileReader, hkVersionRegistry::getInstance(
) );

// Get the contents of the binary packfile.
packfileContents = static_cast(packfileReader.getContents( hkRootLevelContainerClass.getName() ));
// Get the top level object in the file
//hkTypeInfoRegistry reg;
//hkRegisterHavokClasses::registerAll(reg);

//hkpPhysicsData* physicsData = static_cast( packfileReader.getContents( &hkpPhysicsDataClass, &reg ) );

// Store a reference to the physics data in the packfile contents container
physicsData = static_cast(packfileContents->findObjectByType( hkpPhysicsDataClass.getName() ));

WriteToLog("[HavokPhysics 1] physicsData done..size(%d)
", physicsData->getPhysicsSystems().getSize());
(*physicsData->getWorldCinfo()).m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

// Create a world and add the physics systems to it
physicsWorld = new hkpWorld( *physicsData->getWorldCinfo() );

//
// Pre-allocate some larger memory blocks. These are used by the physics system when in multithreaded mode
// The amount and size of these depends on your physics usage. Larger simulation islands will use larger memory blocks.
//
{
hkMemory::getInstance().preAllocateRuntimeBlock(512000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(256000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(128000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(64000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(32000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
}

//
// When the simulation type is SIMULATION_TYPE_MULTITHREADED, in the debug build, the sdk performs checks
// to make sure only one thread is modifying the world at once to prevent multithreaded bugs. Each thread
// must call markForRead / markFo
rWrite before it modifies the world to enable these checks.
//

physicsWorld->markForWrite();

//
// Register all collision agents, even though only box - box will be used in this particular example.
// It's important to register collision agents before adding any entities to the world.
//
{
hkpAgentRegisterUtil::registerAllAgents( physicsWorld->getCollisionDispatcher() );
}

//
// Create a multi-threading utility. This utility will create a number of threads that will run the
// physics step in parallel. The main thread calls functions in the utility which signal these threads
// to start a new step, or wait for step completion.
//
hkpMultithreadingUtilCinfo info;
// Add all the physics systems to the world
for ( int i = 0; i < physicsData->getPhysicsSystems().getSize(); ++i )
{
physicsWorld->addPhysicsSystem( physicsData->getPhysicsSystems()[i] );
}
info.m_world = physicsWorld;
info.m_numThreads = NUM_THREADS;

// In this example we enable timers. The multi-threading util will allocate a buffer per thread for capturing timer data.
// If you leave this flag to false, no timers will be enabled.
info.m_enableTimers = true;
multithreadingUtil = new hkpMultithreadingUtil(info);

//
// Initialize the visual debugger so we can connect remotely to the simulation
// The context must exist beyond the use of the VDB instance, and you can make
// whatever contexts you like for your own viewer types.
//

context = new hkpPhysicsContext();
hkpPhysicsContext::registerAllPhysicsProcesses(); // all the physics viewers
context->addWorld(physicsWorld); // add the physics world so the viewers can see it

hkVisualDebugger* vdb = setupVisualDebugger(context);

context->m_monitorStreamBegins.setSize(NUM_THREADS);
context->m_monitorStreamEnds.setSize(NUM_THREADS);

WriteToLog("[HavokPhysics 2]
physicsData done..size(%d)
", physicsData->getPhysicsSystems().getSize());

for(int i = 0; i < physicsData->getPhysicsSystems().getSize(); i++) {

hkpPhysicsSystem *ps = physicsData->getPhysicsSystems()[i];

for(int j=0; jgetRigidBodies().getSize();j++) {
hkpRigidBody *rb = ps->getRigidBodies()[j] ;

hkpRigidBody *cloney = rb->clone();

rb->removeReference();
WriteToLog("pushing name=%s mass=%f
",cloney->getName(), cloney->getMass());
tempbodies->push_back(cloney);

}

}
physicsWorld->unmarkForWrite();
WriteToLog("Got %d rigid bodies
", tempbodies->size());
}

}
Thanks.

imagem de sean.thurston
Best Reply

Hey gonx,

At the end of your initHavok method, the hkPackfileReader is being deleted because it is a local variable. The hkPackfileData (stored in hkPackFileReader) gets a removeReference() call in the hkPackfileReader destructor. hkPackfileData no longer has any references and is destroyed. It calls the destructors of all the objects it contains and now you are going to get a write access becuase it happens after your unmarkForWrite method call.

I would suggest making the hkPackfileData of the hkPackFileReader a member variable of your class and then calling addReference() when you grab it out of the hkPackFileReader.

I think it would be good to check out the Common Havok Components->Serialization->Memory Considerations of the docs. There is also a short Packfile section under Common Havok Components->Serialization->PackFiles.

One other thing I noticed is that you are calling new hkpWorld() twice. You might want to take a look at that.

Let me know if you have any other problems with this.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
imagem de gonx

Hi sean,

sean.thurston:
At the end of your initHavok method, the hkPackfileReader is being deleted because it is a local variable. The hkPackfileData (stored in hkPackFileReader) gets a removeReference() call in the hkPackfileReader destructor. hkPackfileData no longer has any references and is destroyed. It calls the destructors of all the objects it contains and now you are going to get a write access becuase it happens after your unmarkForWrite method call.

I would suggest making the hkPackfileData of the hkPackFileReader a member variable of your class and then calling addReference() when you grab it out of the hkPackFileReader.

You were right in this one. I placed addRefence for every hkpRigidBody that gave me an access check exception during debug mode and didnt see anymore access exceptions on my release.

sean.thurston:
I think it would be good to check out the Common Havok Components->Serialization->Memory Considerations of the docs. There is also a short Packfile section under Common Havok Components->Serialization->PackFiles.

One other thing I noticed is that you are calling new hkpWorld() twice. You might want to take a look at that.

yes but actually they were commented out. I just forgot to remove it during my posting. Nevertheless thanks for pointing it out.

Many thanks for helping out with this one. I am now able to load an hkx into ogre3d graphics engine and make it move.
it's not much as it just shows a sphere falling on a box. I made the
meshes in autodesk maya. Exported it with the havok content tool and
again exported it into .mesh using blender.

Thanks.

imagem de gonx

Hi,

Has anyone experienced this problem before?

- Using autodesk maya to create 2 meshes. A box and a sphere. Sphere is a moving body falling onto the box.

- Exported to .hkx using havok content tools. *Note transform scene was set to use SCALE_FEET_XXX

- Confirmed with preview scene that sphere falls until it hits the box.

- Loaded hkx unto the graphics engine

- Sphere falls and collides somewhere in mid-air and does not seem to reach the box

- In visual debugger the sphere falls unto the box correctly. This is the same time the sphere stops in mid-air using the main program i made.

Currently i use hkpRigidBody getRotation() and getPosition() to update my main program's graphics object. I could adjust the bodies in my graphics program manually but i'd like to find out if there are other solutions to thisthrough havok content tools.

Thanks.

imagem de sean.thurston

Hey gonx,

The visual debugger shows what the physics engine sees in terms of positions and orientations of rigid bodies. When you look at your box and sphere before they fall, do they look to be the same distance apart when you look at the sphere and the box in the vdb? It might be worth it to look at the sections in the docs under Havok Physics->Physics Articles->Rotation, Handedness, and all that.

I think that this thread might be getting a little cluttered. It might be best for any future problems, after this one, to start a new thread. It will just make the forum a little easier to search for people coming here with problems.

Thanks,
Sean

Developer Support Engineer Havok www.havok.com
imagem de gonx

Will post this one on a different thread. Thanks for your quick reply to my questions

Faça login para deixar um comentário.