Loading a Level into Havok

Loading a Level into Havok

Hey guys, if I create my level on 3DS Max, how can I load it into Havok and let it know that its in the world?  To create the collision with the other objects.  How can I go about this?

9 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.
Portrait de HavokTim

Hi Jose--

Have you installed the content tools? Once you've done so, there will be a Havok toolbar in 3DS Max. In the product manual documentation, you can find a tutorial for exporting in Havok Content Tools >3ds Max Tools. The basics, however, are that you select objects and click on the "RB" button to tag the object as a rigid body. Once ready to export, press the export button and create a series of filters (again, consult the docs for specifics). If you only need the rigid bodies for collision, you can add just a "Create Rigid Bodies" and "Write to Platform" filter. Press "Run Configuration" to export the file into a format Havok can read.

To put these rigid bodies in a physics world in your application, create the world and do something like this:


	hkLoader* loader = ::new hkLoader();

	hkRootLevelContainer* container = loader->load(path.FullPath().CStr());

	assert(container != NULL);

	hkpPhysicsData* physicsData = reinterpret_cast(container->findObjectByType(hkpPhysicsDataClass.getName()));
	if (physicsData != NULL)

	{

		const hkArray& physicsSystems = physicsData->getPhysicsSystems();

		for (int32 i = 0; i < physicsSystems.getSize(); ++i)

		{

			hkpPhysicsSystem* system = physicsSystems[i];

			for (int32 j = 0; j < system->getRigidBodies().getSize(); ++j)

			{

				hkpRigidBody* rigidBody = system->getRigidBodies()[j];
				world->addEntity(rigidBody);

				bodies.PushBack(rigidBody);

			}

		}

	}

--Tim

Thanks for the reply HavokTim. Yes I have downloaded the Content Tools. Still gotta figure out how the tool bar works so I have to find where the documentation is to figure that out. Well mostly I want to collide with the walls of my level. Im going to be creating an indoor setting so I guess what Ill be needing is the Create Rigid Bodies. Probably in the future Ill create some crates or boxes in my level in Max and before adding it in the world I can set them to be dynamic. Is it possible to get the name that Max has for it in this class?

Portrait de HavokTim

Hi Jose--

The Havok documentation is located in /Docs - you'll want to reference the User Guide.

For creating an interior level, you may find it best to create separate collision geometry from the mesh you use for graphics. For fixed terrain, set the mass to zero to keep it from moving. For your character, you probably want to use a character controller - it's described in more detail in the docs under Havok Physics/Extensions/Character Control.

You can invoke hkpRigidBody::getName() on a rigid body to retrieve the name you specified for a given rigid body in 3DS Max.

Please let me know if you have any further questions.

--Tim

Alright I got it to work, thanks. One last question, is there a way in the rigidbody to get its length, height, and width of the object? I need it to render it. I was looking into the rigidbody and also its shape while I was debugging and didnt find anything to get that information.

Portrait de HavokTim

Hi Jose--

The shape of a rigid body is generally used only for the physics simulation; most games and other applications use higher quality display geometry for rendering (and there are performance advantages to using vertex buffers, etc.). Also, be aware that not all rigid bodies will be boxes - Havok supports a wide variety of rigid body shapes. With those caveats, you have two options:

1. Get the extents of the body's AABB: Call hkpRigidBody::getCollidable()->getShape()->getAABB(), then call hkAabb::getExtents() to get a vector whose x, y, and z elements are the bounding box's dimensions. Note that this may not be a tight bounds.

2. If and only if the body is an hkpBoxShape box, get its shape (hkpRigidBody::getCollidable()->getShape()), cast it to hkpBoxShape, and call hkpBoxShape::getHalfExtents() to return an hkVector4 whose x, y, and z are *half* the dimensions of the box. Likewise, the center of the box can be retrieved with hkpBoxShape::getCentre(). Finally, get the rigid body's transform and set the rendering model transform to match.

Let me know if you need any further clarification.

--Tim

Hey HavokTim, I was able to make it work.
I have another issue in loading in Animation Rigs. I was following the User Guide in the Havok Content Tools on how to export animations. Now when I come into loading it it fails in the assert. The file path is in the correct place so there shouldnt be a problem there. Maybe I am missing something. Here is what I am doing.

void Initialize(const char* fileName)

{

	//loadRig

	hkLoader m_loader = new hkLoader();

	hkStringBuf assetFile(fileName);

	hkRootLevelContainer* container = m_loader->load(assetFile.cString());
	HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset");  //it fails here-------------------------
	hkaAnimationContainer* ac = reinterpret_cast(container->findObjectByType(hkaAnimationContainerClass.getName()));

	HK_ASSERT2(0x27343435, ac && (ac->m_skeletons.getSize() > 0), "No skeleton loaded");

	m_skeleton = ac->m_skeletons[0];

}

I was following the SkinningDemo in the MeshAndDeformation folder demo. I even tried to get the rig for the HavokGirl and it still asserts in the same place.

It also uses this:

hkAssetManagementUtil::getFilePath(assetFile);

but I am not using it since I created my own project and linked up havok with Source folder so I dont have access to that hkAssetManagementUtil.
Is it neccessary?

Portrait de HavokTim

Hi Jose--

There are a lot of things that can go wrong when trying to load a file, and it would be helpful to eliminate all of those possibilities before looking for Havok-specific problems. As a first step, can you add the following lines after line 9 in your example code?


	FILE* file = fopen(assetFile.cString(), "r");

	HK_ASSERT2(0x0, file != NULL, "Failed to load file");

If you fail the assert I've added, then the problem is file-related (perhaps the path is slightly wrong, permissions are bad, etc.); otherwise, it means the problem is in the file loading code itself. In either case, let me know what you encounter and we can go from there.

The function hkAssetManagementUtil::getFilePath() is used to validate and sanitize a path string to ensure it's valid across platforms. It should not be strictly necessary - but do check for obvious problems like using '\\' if you use back slashes, and that your working directory is correct if you use relative paths.

Let me know how it goes - thanks!
--Tim

Hey Tim,
I actually have it working. I noticed I never defined the Animation Class #define INCLUDE_HAVOK_ANIMATION_CLASSES.
After that and adding the animation libs it worked fine. Thanks for the help.

Connectez-vous pour laisser un commentaire.