Jump to content
  • Advertisement
Sign in to follow this  
blueShadow

[havok] problem of wrong collision

This topic is 3462 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I want to collide two object just with gravity, one is above the other in my 3d engine. But my problem is that the object which is above falls and stops itself before to be in contact with the other. I use meters in 3ds max to export in .3ds and i use the dimension that i see in 3ds max in my havok program. So, if one object is above the other of 12 meters, i set as position to (0.0f, 12.0f, 0.0f) and the other (the ground) to (0,0,0) and my problem appends here. If i put both to (0,0,0), the object which is above falls infinitely, there is no collision. What can i do ? here is the whole havok part (in my 3d engine i just tranform 3d object by the matrix returned in method : synchronous stepping)
PhysicsHk::PhysicsHk()
{
	instance = this ;
	oneSecond = 0 ;
	//matricesTransformHk = new float[3] ;
	for( int i = 0; i < NUM_BODIES; i++ )
	{
		m_bodies = HK_NULL;		
	}	
	m_currentBody = 0 ;

	hkpWorldCinfo info;
	info.m_gravity = hkVector4(0.0f, -9.8f, 0.0f);
	//gravity = hkVector4(0.0f, -9.8f, 0.0f);
	info.setBroadPhaseWorldSize(10000.0f);
	info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
	info.m_collisionTolerance = 0.001f; 
	info.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_CONTINUOUS;

	memoryManager = new hkPoolMemory();
	threadMemory = new hkThreadMemory (memoryManager);
	hkBaseSystem::init( memoryManager, threadMemory, errorReportFunction );
	int stackSize = 0x60000; // ensure 16 byte aligned
	char* stackBuffer = hkAllocate<char>( stackSize, HK_MEMORY_CLASS_BASE);
	hkThreadMemory::getInstance().setStackArea( stackBuffer, stackSize);

	m_world = new hkpWorld( info );
	//m_world->lock();//Locks the world in a multithreaded environment. 

	// Register the single agent required (a hkpBoxBoxAgent)
	//{
	hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());
	//}

	// Create the rigid bodies
	createBodies();

	// Create the ground
	createGround();

	//m_world->unlock();
}
	

PhysicsHk	*	PhysicsHk::getSingleton()
{
	if (instance == NULL)
		instance = new PhysicsHk();
	return (instance);
}

PhysicsHk::~PhysicsHk()
{
	//m_world->lock();

	for( int i = 0; i < NUM_BODIES; i++ )
	{
		m_bodies->removeReference();
	}

	//m_world->unlock();
}

void PhysicsHk::createGround()
{
	const hkVector4 halfExtents(4.952f, 0.089f/2, 7.31f);
	hkpShape* groundShape = new hkpBoxShape(halfExtents);//, 0.05f );

	hkpRigidBodyCinfo bodyInfo;
	//bodyInfo.m_qualityType = HK_COLLIDABLE_QUALITY_FIXED ;
	bodyInfo.m_mass = 0.0f	;
	bodyInfo.m_shape = groundShape;
	bodyInfo.m_motionType = hkpMotion::MOTION_FIXED;
	bodyInfo.m_position.set(0.0f, 0.0f, 0.0f);
// 	hkVector4 axis(0.0f, 0.0f, 1.0f);
// 	bodyInfo.m_rotation = hkQuaternion(axis, 0.0f);

	groundBody = new hkpRigidBody(bodyInfo);
	groundShape->removeReference();

	m_world->addEntity(groundBody);
	groundBody->removeReference();	
}

void PhysicsHk::createBodies()
{	
	// Each body needs at least one shape
	const hkVector4 halfExtents(0.719f, 2.265f/2, 0.81f);
	hkpShape* shape = new hkpBoxShape(halfExtents);//, 0.05f );

	// Compute the inertia tensor from the shape
	hkpMassProperties massProperties;
	hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, 1000.0f, massProperties);

	// Assign the rigid body properties
	hkpRigidBodyCinfo bodyInfo;
	bodyInfo.m_mass = massProperties.m_mass;
	bodyInfo.m_centerOfMass = massProperties.m_centerOfMass;
	bodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
	bodyInfo.m_shape = shape;
	bodyInfo.m_motionType = hkpMotion::MOTION_DYNAMIC;
	//bodyInfo.m_qualityType = HK_COLLIDABLE_QUALITY_MOVING ;
	bodyInfo.m_position.set(0.0f, 3.0f, 0.0f);

	for(int i = 0; i < NUM_BODIES; i++)
	{
		hkpRigidBody *body = new hkpRigidBody(bodyInfo);
		m_bodies = body;		
	}
	shape->removeReference();

}

void PhysicsHk::addBody(hkpRigidBody* currentBody)
{
	//
	// Add the current body to the simulation
	//

	
	// Zero velocites (still preserved perhaps from previous simulation)
	currentBody->setLinearVelocity(hkVector4::getZero());
	currentBody->setAngularVelocity(hkVector4::getZero());

	// Place above ground, unrotated
// 	hkVector4 position(0.0f, /*505.168f*/0.0f, 0.0f);
// 	currentBody->setPosition(position);
	/*hkQuaternion rot;
	rot.setIdentity();
	currentBody->setRotation(rot);*/

	// Add body
	m_world->addEntity(currentBody);

}

void PhysicsHk::removeBody(hkpRigidBody* body)
{	
	//
	// Remove the current body to the simulation
	//
	m_world->removeEntity(body);	
}

float ** PhysicsHk::synchronousStepping()//BUG : régler le timing
{
	//m_world->lock();

	// add/remove a rigid body
	if((oneSecond % 1000000) == 0)
	{
		oneSecond = 0 ;
		// remove the body if it is already in the world
		if(m_bodies[m_currentBody]->isAddedToWorld())
		{
			removeBody(m_bodies[m_currentBody]);
		}

		// add the body
		addBody(m_bodies[m_currentBody]);

		// move onto the next body
		m_currentBody = (++m_currentBody % NUM_BODIES);
	}
// 	hkTransform transformation = m_bodies[m_currentBody]->getTransform();
// 	transformation.get4x4ColumnMajor(matrixTransformHk);
// 	transformation.setInverse(transformation);
// 	transformation.get4x4ColumnMajor(matrixTransformHk);
	//m_world->unlock();

	/*m_world->stepDeltaTime(0.01f);*/
// 	// Integrate the world forward in time - solves all constraints, and advances all transforms to the next timestep
	m_world->integrate(0.010f);

	// Perform collision detection 
	m_world->collide();

	// Perform continuous simulation
	m_world->advanceTime();

	hkReal* matrixTransformHkBody = new hkReal[16];
	hkTransform transformation = m_bodies[m_currentBody]->getTransform();
	transformation.get4x4ColumnMajor(matrixTransformHkBody);
	matricesTransformHk[0] = matrixTransformHkBody;
	
	hkReal* matrixTransformHkGroundBody = new hkReal[16] ;
	// Apply the antigravity force in the opposite direction to gravity. Its strength is
	// determined by multiplying m_gravity (also a vector) by scale.
	
 	//gravity.setMul4( -1, hkVector4(0.0f, -9.8f, 0.0f));
// 	// This function call actually applies the force to the rigidBody.
 	//groundBody->applyForce(0.010f, gravity );
 	hkTransform transformation2 = groundBody->getTransform();
 	transformation2.get4x4ColumnMajor(matrixTransformHkGroundBody);
 	matricesTransformHk[1] = matrixTransformHkGroundBody ;

	oneSecond += 10 ;
	return matricesTransformHk ;
}

float ** PhysicsHk::getMatrixTransformHk()
{
	return matricesTransformHk ;
}

Share this post


Link to post
Share on other sites
Advertisement
What do you mean when you say that the top object stops before coming into contact with the other? Does it come close? Havok puts a small shell around convex objects to prevent them from penetrating and thus speed up collision resolution. You might be seeing the two objects' shells colliding; you can see whether this is the case by enabling the "convex radius" viewer in the visual debugger. The standard solution to this problem is to shrink your shapes such that the outer boundary of the shell coincides with your render geometry.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!