Skip to content

Instantly share code, notes, and snippets.

@krupitskas
Created January 13, 2015 21:11
Show Gist options
  • Save krupitskas/034c196eb1eca48e741a to your computer and use it in GitHub Desktop.
Save krupitskas/034c196eb1eca48e741a to your computer and use it in GitHub Desktop.
Havok Hello world
/*
*
* Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
* prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
* Product and Trade Secret source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2014 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
*
*/
// Math and base include
#include <Common/Base/hkBase.h>
#include <Common/Base/Memory/System/Util/hkMemoryInitUtil.h>
#include <Common/Base/System/Error/hkDefaultError.h>
#include <Common/Base/Monitor/hkMonitorStream.h>
#include <Common/Base/Config/hkConfigVersion.h>
#include <Common/Base/Memory/System/hkMemorySystem.h>
#include <Common/Base/Memory/Allocator/Malloc/hkMallocAllocator.h>
#include <Common/Base/Container/String/hkStringBuf.h>
// Dynamics includes
#include <Physics2012/Collide/hkpCollide.h>
#include <Physics2012/Collide/Agent/ConvexAgent/SphereBox/hkpSphereBoxAgent.h>
#include <Physics2012/Collide/Shape/Convex/Box/hkpBoxShape.h>
#include <Physics2012/Collide/Shape/Convex/Sphere/hkpSphereShape.h>
#include <Physics2012/Collide/Dispatch/hkpAgentRegisterUtil.h>
#include <Common/Internal/GeometryProcessing/ConvexHull/hkgpConvexHull.h>
#include <Physics2012/Collide/Shape/Convex/Cylinder/hkpCylinderShape.h>
#include <Physics2012/Collide/Shape/Convex/Capsule/hkpCapsuleShape.h>
#include <Physics2012/Collide/Shape/Convex/Triangle/hkpTriangleShape.h>
#include <Physics2012/Collide/Shape/Convex/ConvexVertices/hkpConvexVerticesShape.h>
#include <Physics2012/Dynamics/World/hkpWorld.h>
#include <Physics2012/Dynamics/Entity/hkpRigidBody.h>
#include <Physics2012/Utilities/Dynamics/Inertia/hkpInertiaTensorComputer.h>
// Visual Debugger includes
#include <Common/Visualize/hkVisualDebugger.h>
#include <Physics2012/Utilities/VisualDebugger/hkpPhysicsContext.h>
#include <stdio.h>
#include <stdlib.h>
#if defined( HK_PLATFORM_TIZEN )
#include <osp/FBase.h>
#endif
#ifdef HK_PLATFORM_CTR
#define PRINTF nndbgDetailPrintf
#elif defined(HK_PLATFORM_ANDROID)
#include <android/log.h>
#define PRINTF(...) __android_log_print(ANDROID_LOG_INFO, "Havok", __VA_ARGS__)
#elif defined(HK_PLATFORM_TIZEN)
#define PRINTF(...) AppLogTag("Havok", __VA_ARGS__)
#else
#define PRINTF printf
#endif
#ifdef HK_ANDROID_PLATFROM_8
# include <jni.h>
#endif
void PlatformInit();
void PlatformFileSystemInit();
static void HK_CALL errorReport(const char* msg, void*)
{
PRINTF("%s", msg);
#ifdef HK_PLATFORM_WIN32
#ifndef HK_PLATFORM_WINRT
OutputDebugStringA(msg);
#else
// Unicode only
int sLen = hkString::strLen(msg) + 1;
wchar_t* wideStr = hkAllocateStack<wchar_t>( sLen );
mbstowcs_s(HK_NULL, wideStr, sLen, msg, sLen - 1);
OutputDebugString(wideStr);
hkDeallocateStack<wchar_t>( wideStr, sLen);
#endif
#endif
}
//
// Forward declarations
//
void setupPhysics(hkpWorld* physicsWorld);
hkVisualDebugger* setupVisualDebugger(hkpPhysicsContext* worlds);
void stepVisualDebugger(hkVisualDebugger* vdb);
hkpRigidBody* g_ball;
#if defined(HK_ANDROID_PLATFORM_8)
extern "C" JNIEXPORT jint JNICALL Java_com_havok_ConsoleExample_main(JNIEnv* env)
{
#elif defined(HK_PLATFORM_WINRT) || defined(HK_PLATFORM_DURANGO)
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^ args)
{
#elif defined( HK_PLATFORM_TIZEN )
int hkMain(int argc, const char** argv)
{
#elif !defined(HK_PLATFORM_CTR)
int HK_CALL main(int argc, const char** argv)
{
#else
extern "C" void nnMain( void )
{
int argc = 0;
const char** argv = HK_NULL;
#endif
#ifdef HK_PLATFORM_DURANGO
Windows::Xbox::Networking::SecureDeviceAssociationTemplate::GetTemplateByName("VdbTraffic");
#endif
// Do platform specific initialization
PlatformInit();
// Initialize the base system including our memory system
hkMemorySystem::FrameInfo finfo(500 * 1024); // Allocate 500KB of Physics solver buffer
hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault(hkMallocAllocator::m_defaultMallocAllocator, finfo);
hkBaseSystem::init( memoryRouter, errorReport );
{
// Create the physics world
hkpWorld* physicsWorld;
{
hkpWorldCinfo worldInfo;
worldInfo.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
worldInfo.m_gravity = hkVector4(0.0f, -9.8f, 0.0f);
worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_FIX_ENTITY; // just fix the entity if the object falls off too far
// You must specify the size of the broad phase - objects should not be simulated outside this region
worldInfo.setBroadPhaseWorldSize(1000.0f);
physicsWorld = new hkpWorld(worldInfo);
}
// 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 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.
//
hkpPhysicsContext* 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);
//
// Simulate the world for 1 minute.
// Take fixed time steps of 1/60th of a second.
// This works well if your game runs solidly at 60Hz. If your game runs at 30Hz
// you can take either 2 60Hz steps or 1 30Hz step. Note that at lower frequencies (i.e. 30 Hz)
// more bullet through paper issues appear, and constraints will not be as stiff.
// If you run at variable frame rate, or are likely to drop frames, you can consider
// running your physics for a variable number of steps based on the system clock (i.e. last frame time).
// Please refer to the user guide section on time stepping for a full treatment of this issue.
//
// A stopwatch for waiting until the real time has passed
hkStopwatch stopWatch;
stopWatch.start();
hkReal lastTime = stopWatch.getElapsedSeconds();
hkReal timestep = 1.f / 60.f;
int numSteps = int(60.f / timestep);
for ( int i = 0; i < numSteps; ++i )
{
physicsWorld->stepDeltaTime(timestep);
// Step the visual debugger
stepVisualDebugger(vdb);
// Display the sphereRigidBody position to the console every second
if (i % 60 == 0)
{
hkVector4 pos = g_ball->getPosition();
hkStringBuf msg; msg.printf("[%f,%f,%f]\n", pos(0), pos(1), pos(2));
errorReport(msg.cString(), HK_NULL);
}
// Pause until the actual time has passed
while (stopWatch.getElapsedSeconds() < lastTime + timestep) {}
lastTime += timestep;
// Step the graphics display (none in this demo).
}
//
// Clean up physics and graphics
//
physicsWorld->removeReference();
vdb->removeReference();
// Contexts are not reference counted at the base class level by the VDB as
// they are just interfaces really. So only delete the context after you have
// finished using the VDB.
context->removeReference();
}
// Quit base system
hkBaseSystem::quit();
hkMemoryInitUtil::quit();
#ifndef HK_PLATFORM_CTR
return 0;
#endif
}
void setupPhysics(hkpWorld* physicsWorld)
{
// Create the floor as a fixed box
{
hkpRigidBodyCinfo boxInfo;
hkVector4 boxSize(5.0f, 0.5f , 5.0f);
hkpBoxShape* boxShape = new hkpBoxShape(boxSize);
boxInfo.m_shape = boxShape;
boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
boxInfo.m_position.set(0.0f, 0.0f, 0.0f);
boxInfo.m_restitution = 0.9f;
hkpRigidBody* floor = new hkpRigidBody(boxInfo);
boxShape->removeReference();
physicsWorld->addEntity(floor);
floor->removeReference();
}
//Create Convex Vertices Shape
{
hkReal sphereRadius = 1.0f;
hkpConvexShape* sphereShape = new hkpSphereShape(sphereRadius);
hkpRigidBodyCinfo sphereInfo;
sphereInfo.m_shape = sphereShape;
sphereInfo.m_position.set(0.0f, 100.0f, 1.0f);
sphereInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA;
// Compute mass properties
hkReal sphereMass = 10.0f;
hkMassProperties sphereMassProperties;
hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereRadius, sphereMass, sphereMassProperties);
sphereInfo.m_inertiaTensor = sphereMassProperties.m_inertiaTensor;
sphereInfo.m_centerOfMass = sphereMassProperties.m_centerOfMass;
sphereInfo.m_mass = sphereMassProperties.m_mass;
// Create sphere RigidBody
hkpRigidBody* sphereRigidBody = new hkpRigidBody(sphereInfo);
sphereShape->removeReference();
physicsWorld->addEntity(sphereRigidBody);
g_ball = sphereRigidBody;
sphereRigidBody->removeReference();
}
{
int numVertices = 4;
// A hkReal is a float which has a size of 4 so with the 3 coordinates in a vertex plus its padding the stride
// will equal 16.
int stride = sizeof(hkReal) * 4;
// Define the vertices of the shape.
float vertices[] =
{
-2.0f, 2.0f, 1.0f, 0.0f,
1.0f, 3.0f, 0.0f, 0.0f,
0.0f, 1.0f, 3.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f
};
hkStridedVertices stridedVerts;
stridedVerts.m_numVertices = numVertices;
stridedVerts.m_striding = stride;
stridedVerts.m_vertices = vertices;
hkpConvexVerticesShape::BuildConfig config;
hkpConvexVerticesShape* convexShape = new hkpConvexVerticesShape(stridedVerts, config);
hkpRigidBodyCinfo ci;
// Set its properties.
ci.m_shape = convexShape;
ci.m_position.set(0.0f, 30.0f, 1.0f);
hkpInertiaTensorComputer::setShapeVolumeMassProperties(convexShape, 10.0f, ci);
// Add the rigid body to the world.
hkpRigidBody* thing = new hkpRigidBody(ci);
physicsWorld->addEntity(thing);
convexShape->removeReference();
}
// Create a moving sphere
{
hkReal sphereRadius = 0.5f;
hkpConvexShape* sphereShape = new hkpSphereShape(sphereRadius);
hkpRigidBodyCinfo sphereInfo;
sphereInfo.m_shape = sphereShape;
sphereInfo.m_position.set(0.0f, 50.0f, 0.0f);
sphereInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA;
// Compute mass properties
hkReal sphereMass = 10.0f;
hkMassProperties sphereMassProperties;
hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereRadius, sphereMass, sphereMassProperties);
sphereInfo.m_inertiaTensor = sphereMassProperties.m_inertiaTensor;
sphereInfo.m_centerOfMass = sphereMassProperties.m_centerOfMass;
sphereInfo.m_mass = sphereMassProperties.m_mass;
// Create sphere RigidBody
hkpRigidBody* sphereRigidBody = new hkpRigidBody(sphereInfo);
sphereShape->removeReference();
physicsWorld->addEntity(sphereRigidBody);
g_ball = sphereRigidBody;
sphereRigidBody->removeReference();
}
}
hkVisualDebugger* setupVisualDebugger(hkpPhysicsContext* physicsWorlds)
{
// Setup the visual debugger
hkArray<hkProcessContext*> contexts;
contexts.pushBack(physicsWorlds);
hkVisualDebugger* vdb = new hkVisualDebugger(contexts);
vdb->serve();
// Allocate memory for internal profiling information
// You can discard this if you do not want Havok profiling information
hkMonitorStream& stream = hkMonitorStream::getInstance();
stream.resize( 500 * 1024 ); // 500K for timer info
stream.reset();
return vdb;
}
void stepVisualDebugger(hkVisualDebugger* vdb)
{
// Step the debugger
vdb->step();
// Reset internal profiling info for next frame
hkMonitorStream::getInstance().reset();
}
// Keycode
#include <Common/Base/keycode.cxx>
// This excludes libraries that are not going to be linked
// from the project configuration, even if the keycodes are
// present
#undef HK_FEATURE_PRODUCT_AI
#undef HK_FEATURE_PRODUCT_ANIMATION
#undef HK_FEATURE_PRODUCT_CLOTH
#undef HK_FEATURE_PRODUCT_DESTRUCTION_2012
#undef HK_FEATURE_PRODUCT_DESTRUCTION
#undef HK_FEATURE_PRODUCT_BEHAVIOR
#undef HK_FEATURE_PRODUCT_SIMULATION
#undef HK_FEATURE_PRODUCT_PHYSICS
#define HK_EXCLUDE_LIBRARY_hkpVehicle
#define HK_EXCLUDE_LIBRARY_hkCompat
#define HK_EXCLUDE_LIBRARY_hkSceneData
#define HK_EXCLUDE_LIBRARY_hkcdCollide
//
// Common
//
#define HK_EXCLUDE_FEATURE_SerializeDeprecatedPre700
#define HK_EXCLUDE_FEATURE_RegisterVersionPatches
//#define HK_EXCLUDE_FEATURE_MemoryTracker
//
// Physics
//
#define HK_EXCLUDE_FEATURE_hkpHeightField
//#define HK_EXCLUDE_FEATURE_hkpSimulation
//#define HK_EXCLUDE_FEATURE_hkpContinuousSimulation
//#define HK_EXCLUDE_FEATURE_hkpMultiThreadedSimulation
#define HK_EXCLUDE_FEATURE_hkpAccurateInertiaTensorComputer
#define HK_EXCLUDE_FEATURE_hkpUtilities
#define HK_EXCLUDE_FEATURE_hkpVehicle
#define HK_EXCLUDE_FEATURE_hkpCompressedMeshShape
#define HK_EXCLUDE_FEATURE_hkpConvexPieceMeshShape
#define HK_EXCLUDE_FEATURE_hkpExtendedMeshShape
#define HK_EXCLUDE_FEATURE_hkpMeshShape
#define HK_EXCLUDE_FEATURE_hkpSimpleMeshShape
#define HK_EXCLUDE_FEATURE_hkpPoweredChainData
#define HK_EXCLUDE_FEATURE_hkMonitorStream
#include <Common/Base/Config/hkProductFeatures.cxx>
// Platform specific initialization
#include <Common/Base/System/Init/PlatformInit.cxx>
/*
* Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20140907)
*
* Confidential Information of Havok. (C) Copyright 1999-2014
* Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
* Logo, and the Havok buzzsaw logo are trademarks of Havok. Title, ownership
* rights, and intellectual property rights in the Havok software remain in
* Havok and/or its suppliers.
*
* Use of this software for evaluation purposes is subject to and indicates
* acceptance of the End User licence Agreement for this product. A copy of
* the license is included with this software and is also available at www.havok.com/tryhavok.
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment