Пример #1
0
DumpClassListDemo::DumpClassListDemo( hkDemoEnvironment* env) 
	: hkDefaultDemo(env) 
{
	hkString filePath("Common/Api/Serialize/Versioning/DumpClassList/");
	hkString fileName = hkString(hkVersionUtil::getCurrentVersion()).replace("-","").replace(".","")+"Classes";
	const char registryVariableName[] = "CustomStaticRegistry";

	// Dump all currently reflected runtime classes
	// Open a stream to write the cpp header file
	{
		hkOstream outfile( hkString(filePath + fileName + ".h").cString() );
		HK_ASSERT2( 0x215d080f, outfile.isOk(), "Could not open '" << fileName.cString() << "h' for writing." );
		// extern the runtime classes into the header file
		hkVersionUtil::generateCppExternClassList(outfile, fileName.replace(".","_").asUpperCase().cString(), classes, registryVariableName);
	}
	// Open a stream to write the cpp source file
	{
		hkOstream outfile( hkString(filePath + fileName + ".cpp").cString() );
		HK_ASSERT2( 0x215d0810, outfile.isOk(), "Could not open '" << fileName.cString() << "cpp' for writing." );
		// set demos pch file
		const char* pchfilename = "demos/Demos.h";
		// dump the runtime classes into the cpp file
		hkVersionUtil::generateCppClassList(outfile, classes, pchfilename, registryVariableName);
	}
}
Пример #2
0
hkString TweakerUtils::clearData(const hkString& memberPath, void* rootData, const hkClass& rootKlass)
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(memberPath, rootData, rootKlass, data, klass);

	hkString memberName = memberPath;
	if (classPath.getLength() > 0)
		memberName = memberName.replace(classPath, hkString(""));

	int memberIdx = getMemberIdx(memberName, *klass);
	if (memberIdx < 0)
		return classPath;

	const hkClassMember& member = klass->getMember(memberIdx);
	void* memberData = static_cast<void*>(static_cast<char*>(data) + member.getOffset());

	hkString str;
	switch (member.getType())
	{
	case hkClassMember::TYPE_REAL :
		{
			hkReal& value = lookupMember<hkReal>(memberData);
			value = 0.0f;
		}
		break;
	case hkClassMember::TYPE_INT32 :
		{
			hkInt32& value = lookupMember<hkInt32>(memberData);
			value = 0;
		}
		break;
	case hkClassMember::TYPE_UINT32 :
		{
			hkUint32& value = lookupMember<hkUint32>(memberData);
			value = 0;
		}
		break;
	case hkClassMember::TYPE_BOOL :
		{
			bool& value = lookupMember<bool>(memberData);
			value = static_cast<bool>(0);
		}
		break;
	case hkClassMember::TYPE_ENUM :
		{
			const hkClassEnum& e = member.getEnumType();
			member.setEnumValue(memberData, e.getItem(0).getValue());
		}
		break;
	default:
		break;
	}

	return memberPath;
}
Пример #3
0
hkString TweakerUtils::getPrevSiblingPath(	const hkString& memberPath, const void* rootData, const class hkClass& rootKlass,
										HideMemberFunc hideMember )
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(memberPath, rootData, rootKlass, data, klass);

	hkString memberName = memberPath;
	if (classPath.getLength() > 0)
		memberName = memberName.replace(classPath, hkString(""));

	int leftBracketIndex = memberName.indexOf('[');
	int arrayIndex = -1;

	if ( leftBracketIndex != -1 )
	{
		int rightBracketIndex = memberName.indexOf(']');
		hkString indexString = memberName.substr( leftBracketIndex+1, rightBracketIndex - leftBracketIndex - 1 );
		arrayIndex = hkString::atoi( indexString.cString() );
		memberName = memberName.substr( 0, leftBracketIndex );
	}

	int memberIdx = getMemberIdx(memberName, *klass);

	if ( (memberIdx != -1) && (arrayIndex != -1) )
	{
		const hkClassMember& member = klass->getMember(memberIdx);

		if ( member.getType() == hkClassMember::TYPE_ARRAY )
		{
			void* memberData = static_cast<void*>(static_cast<char*>(data) + member.getOffset());
			hkArray<char>* arrayPtr = static_cast<hkArray<char>*>(memberData);
			int sz = arrayPtr->getSize();

			int newIndex = (arrayIndex + sz - 1) % sz;

			hkString s;
			s.printf( "%s%s[%d]", classPath.cString(), memberName.cString(), newIndex );
			return s;
		}
	}

	if ( memberIdx == -1 )
	{
		memberIdx = 0;
	}

	do
	{
		memberIdx = ( memberIdx - 1 + klass->getNumMembers()) % klass->getNumMembers();
	} while ( hideMember && hideMember(klass->getMember(memberIdx)) );

	return classPath + hkString( klass->getMember(memberIdx).getName());
}
Пример #4
0
hkString TweakerUtils::getParentPath(const hkString& memberPath, const void* rootData, const class hkClass& rootKlass)
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	if ( memberPath[memberPath.getLength()-1] == ']' )
	{
		int leftBracketIndex = memberPath.lastIndexOf('[');
		return memberPath.substr( 0, leftBracketIndex );
	}

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(memberPath, rootData, rootKlass, data, klass);

	// Remove trailing /
	while (classPath.endsWith("/"))
		classPath = classPath.substr(0, classPath.getLength() -1);

	return classPath;
}
hkgShaderCollection* HardwareSkinningDemo::compileShader()
{
	hkgShaderCollection* ret  = HK_NULL;

	hkgDisplayContext* ctx = m_env->m_window->getContext();
	hkgShader* vertexShader = hkgShader::createVertexShader( ctx );
	hkgShader* pixelShader = hkgShader::createPixelShader( ctx );

	hkString shaderFile("./Resources/Animation/Shaders/SimpleSkinningShader"); 
	shaderFile += hkString(vertexShader->getDefaultFileNameExtension());

	vertexShader->realizeCompileFromFile( shaderFile.cString(), "mainVS", HK_NULL, HK_NULL, HK_NULL);
	pixelShader->realizeCompileFromFile( shaderFile.cString(), "mainPS", HK_NULL, HK_NULL, HK_NULL);

	ret = hkgShaderCollection::create();
	ret->addShaderGrouping(vertexShader, pixelShader);	

	pixelShader->removeReference();
	vertexShader->removeReference();

	return ret;
}
Пример #6
0
void Gdc2005Demo::handleTweakingInput()
{
	const bool usingGamepad = m_env->m_window->hasGamePads() && !m_env->m_options->m_forceKeyboardGamepad;
	const hkgKeyboard& keys = m_env->m_window->getKeyboard();

	if ( m_env->m_gamePad->wasButtonPressed(HKG_PAD_SELECT) ||
		keys.wasKeyPressed('T') )
	{
		m_tweaking = !m_tweaking;
	}

	if (m_tweaking)
	{
		// Show help on the keys
		showKeys();

		if (m_selected[0]!='/')
			m_selected = "/";

		extern const hkClass Gdc2005DemoOptionsClass;
		const hkClass& klass = Gdc2005DemoOptionsClass;
		hkgPad* pad = m_env->m_gamePad;

		if (pad->wasButtonPressed(HKG_PAD_DPAD_DOWN))
		{
			m_selected = TweakerUtils::getNextSiblingPath(m_selected, &m_options, klass);
		}

		if (pad->wasButtonPressed(HKG_PAD_DPAD_UP))
		{
			m_selected = TweakerUtils::getPrevSiblingPath(m_selected, &m_options, klass);
		}

		if (pad->wasButtonPressed(HKG_PAD_DPAD_LEFT))
		{
			m_selected = TweakerUtils::getParentPath(m_selected, &m_options, klass);
		}

		if (pad->wasButtonPressed(HKG_PAD_DPAD_RIGHT))
		{
			m_selected = TweakerUtils::getChildPath(m_selected, &m_options, klass);
		}

		if (usingGamepad)
		{
			if (pad->wasButtonPressed(HKG_PAD_BUTTON_0 ))
			{
				TweakerUtils::tweakData(m_selected, &m_options, klass, -0.1f);
			}

			if (pad->wasButtonPressed(HKG_PAD_BUTTON_3))
			{
				TweakerUtils::tweakData(m_selected, &m_options, klass, 0.1f);
			}

			if (pad->wasButtonPressed(HKG_PAD_BUTTON_2))
			{
				TweakerUtils::clearData(m_selected, &m_options, klass);
			}
		}
		else
		{
			if ( keys.wasKeyPressed(HKG_VKEY_SUBTRACT) || keys.wasKeyPressed(HKG_VKEY_SPACE) ||
				keys.wasKeyPressed(HKG_VKEY_OEM_MINUS) || keys.wasKeyPressed(HKG_VKEY_OEM_COMMA) )
			{
				TweakerUtils::tweakData(m_selected, &m_options, klass, -0.1f);
			}

			if ( keys.wasKeyPressed(HKG_VKEY_ADD) || keys.wasKeyPressed(HKG_VKEY_OEM_PLUS) || keys.wasKeyPressed(HKG_VKEY_OEM_PERIOD) )
			{
				TweakerUtils::tweakData(m_selected, &m_options, klass, 0.1f);
			}

			if ( keys.wasKeyPressed('0') || keys.wasKeyPressed(HKG_VKEY_DELETE) || keys.wasKeyPressed(HKG_VKEY_NUMPAD0) )
			{
				TweakerUtils::clearData(m_selected, &m_options, klass);
			}
		}

		TweakerUtils::displayData(m_selected, &m_options, klass, *m_env->m_textDisplay, 40, 40);

		m_env->m_textDisplay->outputText( hkString("Tweaking: ") + m_selected, 40, 15, 0xffffffff);

		// Clean out the pad so the keypresses don't propagate below.
		hkString::memSet( pad, 0, sizeof(hkgPad));
	}
}
hkgShaderCollection* HardwareSkinningDemo::loadPrecompiledShader()
{

	const char* filePostfix = hkgSystem::g_RendererType == hkgSystem::HKG_RENDERER_DX8? "_vs11_dx81" : "_vs20_dx9";
	const char* filePrefix = ".\\";


	hkString shaderFile;
	hkString pshaderFile;
	hkString resources("resources\\animation\\shaders\\");
	hkString filename;
	filename = hkString(filePrefix) + resources + "Skinning" + filePostfix;
	shaderFile = filename + ".vso";
	pshaderFile = filename + ".pso";

	hkIstream shaderFileStream( shaderFile.cString() );
	HK_ASSERT(0x0, shaderFileStream.isOk());
	HKG_SHADER_RENDER_STYLE style = HKG_SHADER_RENDER_1LIGHTS;  // one spot light
	hkgShader* shader = hkgShader::create(HKG_VERTEX_SHADER, m_env->m_window->getContext());
	shader->setShaderFileName( shaderFile.cString() );
	shader->realize(shaderFileStream, style);

	// add a pixel shader if require (just always use one..)
	hkgShader* pshader = HK_NULL;
    if (hkgSystem::g_RendererType == hkgSystem::HKG_RENDERER_DX9S)
	{
		// need a precompiled pixel shader..
		HK_ASSERT(0x0, "Demo does not make a precompiled pixel shader for d3d9s");
	}


	/*	// Vertex Shader
	//   -------------- ----- ----
	//   mWorldMatrixArray c0      78
	//   mViewProj         c78      4
	//   lhtDir            c82      1
	//   MaterialAmbient   c83      1
	//   MaterialDiffuse   c84      1
	*/

	// table of 26 matrices first
	for (int i=0; i < 26; ++i)
		shader->addMatInput(HKG_SHADER_MAT_INPUT_4x4, 12);

	// add the rest of the actually auto set constants:
	shader->addMatInput(HKG_SHADER_MAT_INPUT_VP, 16);
	shader->addNormalInput(HKG_SHADER_INPUT_LIGHT_DIR, 4);
	shader->addNormalInput(HKG_SHADER_INPUT_AMBIENT_COLOR, 4);
	shader->addNormalInput(HKG_SHADER_INPUT_DIFFUSE_COLOR, 4);


	/*	// Pixel Shader
	//   -------------- ----- ----
	// just the texture in s0
	*/

	// Group the set of shaders together
	hkgShaderCollection* effect = hkgShaderCollection::create();
	effect->addShaderGrouping(shader, pshader);
	if (shader) shader->release();
	if (pshader) pshader->release();

	return effect;
}
// This function is used to generate the binding. It compares bone names and track names and indicates when they match (returns 0)
int HK_CALL bindingCompare( const char* boneName, const char* trackName )
{
	return ( hkString(trackName).beginsWith( boneName ) ? 0 : 1);
}
NativePackfileLoadDemo::NativePackfileLoadDemo( hkDemoEnvironment* env) 
	: hkDefaultPhysicsDemo(env)
{
	// Disable warning: 'm_contactRestingVelocity not set, setting it to REAL_MAX, so that the new collision restitution code will be disabled'
	hkError::getInstance().setEnabled(0xf03243ed, false);
	hkError::getInstance().setEnabled(0x9fe65234, false);
	
	// Setup the camera
	{
		hkVector4 from(31, 31, 14);
		hkVector4 to(2.5f, -2, -.3f);
		hkVector4 up(0, 0, 1);
		setupDefaultCameras( env, from, to, up );
	}

	hkString path("Resources/Common/Api/Serialize/SimpleLoad");
	hkString fileName;
	NativePackfileLoadDemo_getBinaryFileName(fileName);

	hkRootLevelContainer* container = HK_NULL;

	{
		// read entire file into local buffer
		hkArray<char> buf;
		loadEntireFileIntoBuffer( hkString(path+fileName).cString(), buf );

#if defined(PACKFILE_LOAD_WITH_VERSIONING)
		updatePackfileDataVersion( buf );
#endif
		// Now we have native packfile data in the 'buf' variable.

		// extract only valuable data, stripping out all extras, such as headers and fixups tables
		// and load it into m_dataBuffer
		int bufferSize = hkNativePackfileUtils::getRequiredBufferSize( buf.begin(), buf.getSize() );
		m_dataBuffer.reserveExactly(bufferSize);

		// Load the buffer and get the top level object in the file in one step
		container = static_cast<hkRootLevelContainer*>(hkNativePackfileUtils::load(buf.begin(), buf.getSize(), m_dataBuffer.begin(), m_dataBuffer.getCapacity()));
	}
	HK_ASSERT2(0xa6451543, container != HK_NULL, "Could not load root level obejct" );
	hkpPhysicsData* physicsData = static_cast<hkpPhysicsData*>( container->findObjectByType( hkpPhysicsDataClass.getName() ) );
	HK_ASSERT2(0xa6451544, physicsData != HK_NULL, "Could not find physics data in root level object" );
	HK_ASSERT2(0xa6451535, physicsData->getWorldCinfo() != HK_NULL, "No physics cinfo in loaded file - cannot create a hkpWorld" );

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

	// Register all collision agents
	hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );

	// Add all the physics systems to the world
	for ( int i = 0; i < physicsData->getPhysicsSystems().getSize(); ++i )
	{
		m_world->addPhysicsSystem( physicsData->getPhysicsSystems()[i] );
	}

	// Setup graphics - this creates graphics objects for all rigid bodies and phantoms in the world
	setupGraphics();

	m_world->unlock();
}
Пример #10
0
hkString TweakerUtils::tweakData(const hkString& memberPath, void* rootData, const hkClass& rootKlass, float offset, const hkReal threshold, FloatTweakType floatTweakType)
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(memberPath, rootData, rootKlass, data, klass);

	hkString memberName = memberPath;
	if (classPath.getLength() > 0)
		memberName = memberName.replace(classPath, hkString(""));

	// deal with arrays

	int rightBracketIndex = memberName.indexOf( ']' );
	int arrayIndex = -1;

	if ( rightBracketIndex != -1 )
	{
		int leftBracketIndex = memberName.indexOf( '[' );
		hkString indexString = memberName.substr( leftBracketIndex + 1, rightBracketIndex - leftBracketIndex - 1 );
		arrayIndex = hkString::atoi( indexString.cString() );
		memberName = memberName.substr( 0, leftBracketIndex );
	}

	int memberIdx = getMemberIdx(memberName, *klass);
	if (memberIdx < 0)
		return classPath;

	const hkClassMember& member = klass->getMember(memberIdx);
	void* memberData = static_cast<void*>(static_cast<char*>(data) + member.getOffset());

	hkString str;
	switch (member.getType())
	{
	case hkClassMember::TYPE_REAL :
		{

			switch(floatTweakType)
			{
				case MULTIPLICATIVE:
				{
					hkReal& value = lookupMember<hkReal>(memberData);
					value *= (value > 0) ? 1.0f + offset : 1.0f - offset;


					// On 0 snap to +ve or -ve
					if ( value == 0.0f )
					{
						value = (offset > 0) ? threshold : -threshold;
					}

					// Snap to 0 exactly
					if (hkMath::fabs(value) < threshold)
					{
						value = 0.0f;
					}
					break;
				}
				case ADDITIVE:
				{
					hkReal& value = lookupMember<hkReal>(memberData);
					value += offset;					
				}

			}
		}
		break;
	case hkClassMember::TYPE_INT32 :
		{
			hkInt32& value = lookupMember<hkInt32>(memberData);
			hkInt32 offsetAsInt = convertTweakerFloatToInt(offset);
			value += offsetAsInt;
		}
		break;
	case hkClassMember::TYPE_UINT32 :
		{
			hkUint32& value = lookupMember<hkUint32>(memberData);
			hkInt32 offsetAsInt = convertTweakerFloatToInt(offset);
			value += offsetAsInt;
		}
		break;
	case hkClassMember::TYPE_INT16 :
		{
			hkInt16& value = lookupMember<hkInt16>(memberData);
			hkInt32 offsetAsInt = convertTweakerFloatToInt(offset);
			value = hkInt16( value + offsetAsInt);
		}
		break;
	case hkClassMember::TYPE_UINT16 :
		{
			hkUint16& value = lookupMember<hkUint16>(memberData);
			hkInt32 offsetAsInt = convertTweakerFloatToInt(offset);
			value = hkUint16( value + offsetAsInt);
		}
		break;
	case hkClassMember::TYPE_BOOL :
		{
			bool& value = lookupMember<bool>(memberData);
			value = !value;
		}
		break;
	case hkClassMember::TYPE_ENUM :
		{
			const hkClassEnum& e = member.getEnumType();
			int value = member.getEnumValue(memberData);

			// Find item with current value
			int itemIdx = 0;
			while ( e.getItem(itemIdx).getValue() != value)
				itemIdx++;

			itemIdx += (offset > 0) ? 1 : e.getNumItems() -1;
			itemIdx = itemIdx % e.getNumItems();

			member.setEnumValue(memberData, e.getItem(itemIdx).getValue());
		}
		break;
	case hkClassMember::TYPE_ARRAY :
		{
			switch( member.getSubType() )
			{
				case hkClassMember::TYPE_INT32 :
				{
					void* ptrAddr = static_cast<void*>(memberData);
					hkArray<hkInt32>* arrayPtr = static_cast<hkArray<hkInt32>*>( ptrAddr );
					(*arrayPtr)[arrayIndex] += (offset > 0) ? 1 : -1;
					break;
				}
				default:
				{
					break;
				}
			}
		}
		break;
	default:
		break;
	}

	return memberPath;
}
Пример #11
0
hkString TweakerUtils::setReal( const hkString& memberPath, void* rootData, const hkClass& rootKlass, float newValue )
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(memberPath, rootData, rootKlass, data, klass);

	hkString memberName = memberPath;
	if (classPath.getLength() > 0)
		memberName = memberName.replace(classPath, hkString(""));

	// deal with arrays

	int rightBracketIndex = memberName.indexOf( ']' );
	int arrayIndex = -1;

	if ( rightBracketIndex != -1 )
	{
		int leftBracketIndex = memberName.indexOf( '[' );
		hkString indexString = memberName.substr( leftBracketIndex + 1, rightBracketIndex - leftBracketIndex - 1 );
		arrayIndex = hkString::atoi( indexString.cString() );
		memberName = memberName.substr( 0, leftBracketIndex );
	}

	int memberIdx = getMemberIdx(memberName, *klass);
	if (memberIdx < 0)
		return classPath;

	const hkClassMember& member = klass->getMember(memberIdx);
	void* memberData = static_cast<void*>(static_cast<char*>(data) + member.getOffset());

	hkString str;
	switch (member.getType())
	{
	case hkClassMember::TYPE_REAL :
		{
			hkReal& value = lookupMember<hkReal>(memberData);

			value = newValue;
		}
		break;
	case hkClassMember::TYPE_INT32 :
		{
			hkInt32& value = lookupMember<hkInt32>(memberData);
			value = hkInt32(newValue);
		}
		break;
	case hkClassMember::TYPE_UINT32 :
		{
			hkUint32& value = lookupMember<hkUint32>(memberData);
			value = hkUint32(newValue);
		}
		break;
	case hkClassMember::TYPE_INT16 :
		{
			hkInt16& value = lookupMember<hkInt16>(memberData);
			value = hkInt16(newValue);
		}
		break;
	case hkClassMember::TYPE_UINT16 :
		{
			hkUint16& value = lookupMember<hkUint16>(memberData);
			value = hkUint16(newValue);
		}
		break;
	case hkClassMember::TYPE_BOOL :
		{
			bool& value = lookupMember<bool>(memberData);
			value = (newValue!=0.0f);
		}
		break;
	case hkClassMember::TYPE_ENUM :
		{
			// for backward compatibility we clear the data on zero, otherwise do nothing to enums
			if ( newValue == 0.0f )
			{
				const hkClassEnum& e = member.getEnumType();
				member.setEnumValue(memberData, e.getItem(0).getValue());
			}
		}
		break;
	case hkClassMember::TYPE_ARRAY:
		{
			switch( member.getSubType() )
			{
			case hkClassMember::TYPE_REAL :
				{
					void* ptrAddr = static_cast<void*>(memberData);
					hkArray<hkReal>* arrayPtr = static_cast<hkArray<hkReal>*>( ptrAddr );
					(*arrayPtr)[arrayIndex] = newValue;
				}
				break;
			case hkClassMember::TYPE_INT32 :
				{
					void* ptrAddr = static_cast<void*>(memberData);
					hkArray<hkInt32>* arrayPtr = static_cast<hkArray<hkInt32>*>( ptrAddr );
					(*arrayPtr)[arrayIndex] = static_cast<hkInt32>(newValue);
				}
				break;
			default:
				break;
			}
		}
		break;
	default:
		break;
	}

	return memberPath;
}
Пример #12
0
hkString TweakerUtils::getClass(	const hkString& memberPath, const void* rootData, const class hkClass& rootKlass,
									void*& data, const hkClass*& klass,
									HideMemberFunc hideMember )
{
	hkString path = memberPath;

	// Strip leading '/'
	while (path[0] == '/')
		path = path.substr(1);

	// Empty string
	if (path.getLength() == 0)
	{
		data = const_cast<void*>(rootData);
		klass = &rootKlass;
		return hkString("/");
	}

	// Find next '/'
	int idx = path.indexOf('/');
	if (idx < 0) idx = path.getLength();

	// find next '['

	int leftBracketIndex = path.indexOf( '[' );
	if (leftBracketIndex < 0) leftBracketIndex = path.getLength();

	hkBool isArray = ( leftBracketIndex < idx );
	hkString memberName;
	int arrayIndex = -1;
	hkString memberNameAndIndex;

	if ( isArray )
	{
		int rightBracketIndex = path.indexOf(']');
		hkString indexString = path.substr( leftBracketIndex+1, rightBracketIndex - leftBracketIndex - 1 );
		arrayIndex = hkString::atoi( indexString.cString() );
		memberName = path.substr(0, leftBracketIndex );
		memberNameAndIndex = path.substr(0, rightBracketIndex+1);
		path = path.substr(rightBracketIndex+1);
	}
	else
	{
		memberName = path.substr(0, idx);
		path = path.substr(idx); // now holds remaining path
	}

	// Check the klass has this member
	int memberIdx = getMemberIdx( memberName, rootKlass);

	// Member not found so return
	if (memberIdx == -1)
	{
		data = const_cast<void*>(rootData);
		klass = &rootKlass;
		return hkString("");
	}

	const hkClassMember& member = rootKlass.getMember( memberIdx );

	// Chase pointers to structs / classes

	if (path.getLength() > 0)
	{
		if (member.getType() == hkClassMember::TYPE_STRUCT)
		{
			const void* ptrAddr = static_cast<const char*>(rootData) + member.getOffset();
			return hkString("/") + memberName +
				TweakerUtils::getClass(path, ptrAddr, member.getStructClass(), data, klass);
		}
		else if (( member.getType() ==  hkClassMember::TYPE_POINTER) && (member.getSubType() == hkClassMember::TYPE_STRUCT))
		{
			const void* ptrAddr = static_cast<const char*>(rootData) + member.getOffset();
			const void* ptrTo = *static_cast<const void*const*>(ptrAddr);
			const hkClass* instanceClass = getInstanceClass( &member.getStructClass(), ptrTo );

			return hkString("/") + memberName +
				TweakerUtils::getClass(path, ptrTo, *instanceClass, data, klass);
		}
		else if (( member.getType() == hkClassMember::TYPE_ARRAY ) && isArray )
		{
			if ( member.getSubType() == hkClassMember::TYPE_STRUCT )
			{
				const void* ptrAddr = static_cast<const char*>(rootData) + member.getOffset();
				const hkArray<char>* arrayPtr = static_cast<const hkArray<char>*>( ptrAddr );
				int sz = member.getArrayMemberSize();
				const void* memberData = arrayPtr->begin() + sz*arrayIndex;

				return hkString("/") + memberNameAndIndex +
					TweakerUtils::getClass(path, memberData, member.getStructClass(), data, klass);
			}
			else if ( member.getSubType() == hkClassMember::TYPE_POINTER )
			{
				const void* arrayData = static_cast<const void*>(static_cast<const char*>(rootData) + member.getOffset());
				const hkArray<void*>* arrayPtr = static_cast<const hkArray<void*>*>( arrayData );
				const void* ptrTo = *(arrayPtr->begin() + arrayIndex);
				const hkClass* instanceClass = getInstanceClass( &member.getStructClass(), ptrTo );

				return hkString("/") + memberNameAndIndex +
						TweakerUtils::getClass(path, ptrTo, *instanceClass, data, klass);
			}
			else
			{
				return memberPath;
			}
		}
	}

	// Return this class
	data = const_cast<void*>(rootData);
	klass = &rootKlass;
	return hkString("/");
}
Пример #13
0
hkString TweakerUtils::getChildPath(	const hkString& memberPath, const void* rootData, const class hkClass& rootKlass,
										HideMemberFunc hideMember )
{
	if (memberPath.getLength() == 0)
		return hkString("/");

	if ( memberPath.endsWith("]") )
	{
		// getClass only returns the class of the array element type if a slash is at the end
		hkString path;
		path = memberPath + hkString("/");

		const hkClass* klass = 0;
		void* data;
		hkString classPath = TweakerUtils::getClass(path, rootData, rootKlass, data, klass);

		if ( klass && ( klass->getNumMembers() > 0 ) )
		{
			for( int i = 0; i < klass->getNumMembers(); i++ )
			{
				const hkClassMember& member = klass->getMember(i);
				if( NOT( hideMember && hideMember(member) ) )
				{
					return classPath + member.getName();
				}
			}

			// all of the members filtered out so we just return the parent path that was passed in
			return memberPath;
		}

		return memberPath;
	}

	hkString path;
	path = memberPath;

	const hkClass* klass;
	void* data;
	hkString classPath = TweakerUtils::getClass(path, rootData, rootKlass, data, klass);

	int memberIdx;
	{
	hkString memberName = path;
	if (classPath.getLength() > 0)
		memberName = memberName.replace(classPath, hkString(""));

		memberIdx = getMemberIdx(memberName, *klass);
	}

	// Couldn't find the member
	if (memberIdx == -1)
	{
		if (rootKlass.getNumMembers() > 0)
		{
			for( int i = 0; i < rootKlass.getNumMembers(); i++ )
			{
				const hkClassMember& member = rootKlass.getMember(i);
				if( NOT( hideMember && hideMember(member) ) )
				{
					return classPath + member.getName();
				}
			}
		}
	}

	const hkClassMember& member = klass->getMember(memberIdx);

	if ( member.getType() ==  hkClassMember::TYPE_STRUCT)
	{
		const hkClass& childClass = member.getStructClass();
		if (childClass.getNumMembers() > 0)
		{
			for( int i = 0; i < childClass.getNumMembers(); i++ )
			{
				const hkClassMember& mem = childClass.getMember(i);
				if( NOT( hideMember && hideMember(mem) ) )
				{
					return memberPath + "/" + mem.getName();
				}
			}

			return memberPath;
		}
	}
	else if (( member.getType() ==  hkClassMember::TYPE_POINTER) && (member.getSubType() == hkClassMember::TYPE_STRUCT))
	{
		const void* ptrAddr = const_cast<const char*> (static_cast<char*>(data) + member.getOffset() );
		const void* ptrTo = *static_cast<const void*const*>(ptrAddr);

		const hkClass& childClass = *getInstanceClass( &member.getStructClass(), ptrTo );

		if ( ptrTo && ( childClass.getNumMembers() > 0 ) )
		{
			for( int i = 0; i < childClass.getNumMembers(); i++ )
			{
				const hkClassMember& mem = childClass.getMember(i);
				if( NOT( hideMember && hideMember(mem) ) )
				{
					return memberPath + "/" + mem.getName();
				}
			}

			return memberPath;
		}
	}
	else if ( member.getType() == hkClassMember::TYPE_ARRAY )
	{
		// check to see if it is an empty array or not

		const void* ptrAddr = const_cast<const char*>( static_cast<char*>(data) + member.getOffset() );
		const hkArray<char>* arrayPtr = static_cast<const hkArray<char>*>( ptrAddr );

		if ( arrayPtr->getSize() )
		{
			return memberPath + "[0]"; // first element
		}
	}

	return memberPath;
}
Пример #14
0
hkDemo::Result TestPlanDemo::stepDemo()
{
	hkString testPlanFilename;
	if( m_testPlanType == DEMOS_LIST )
	{
		testPlanFilename.printf( "%s.txt", m_testPlanFilename );
	}
	else
	{
		testPlanFilename.printf( "%s_%i_%sReport.csv", HAVOK_SDK_VERSION_STRING, HAVOK_BUILD_NUMBER, m_testPlanFilename );
	}

	if( m_step == 0 )
	{
		hkOfstream ostr( testPlanFilename.cString() );

		if( m_testPlanType == TEST_PLAN_UNIT_TESTS )
		{
			ostr.printf( "%s,\n", unitTestCols );
		}
		else if( m_testPlanType != DEMOS_LIST )
		{
			ostr.printf( "%s,\n", demoCols );
		}

		//
		// Get a list of the demos and build a test plan
		//
		hkObjectArray<hkString> demoPathItems;
		const hkObjectArray<hkDemoEntry>& db = hkDemoDatabase::getInstance().getDemos();

		for( int i=0; i<db.getSize(); i++ )
		{
			const hkDemoEntry& entry = db[i];
			hkString demoName = entry.m_menuPath.replace(","," -");

			bool unitTest = entry.m_demoTypeFlags & HK_DEMO_TYPE_TEST
				&& demoName.substr( demoName.indexOf('/')+1, 4 ) == "Test" 
				&& demoName.substr( demoName.indexOf('/')+6, 8 ) == "UnitTest";

			// Skip demos based on their location in the demos tree.
			switch (m_testPlanType)
			{
			case DEMOS_LIST:
				// Simply print out the demo name, skipping the path processing after the switch.
				ostr.printf( "\"%s\"\n", demoName.cString() );
				continue;

			case TEST_PLAN_ALL:
				// Don't skip any demos.
				break;

			case TEST_PLAN_COMMON_DEMOS:
				if ( demoName.substr(0,6) != hkString("Common") || unitTest )
				{
					continue;
				}
				break;

			case TEST_PLAN_PHYSICS_DEMOS:
				if ( demoName.substr(0,7) != hkString("Physics") || unitTest )
				{
					continue;
				}
				break;

			case TEST_PLAN_ANIMATION_DEMOS:
				if ( demoName.substr(0,9) != hkString("Animation") || unitTest )
				{
					continue;
				}
				break;

			case TEST_PLAN_BEHAVIOR_DEMOS:
				if ( demoName.substr(0,8) != hkString("Behavior") || unitTest )
				{
					continue;
				}
				break;

			case TEST_PLAN_SERIALIZE_DEMOS:
				if( (entry.m_demoTypeFlags & HK_DEMO_TYPE_SERIALIZE) == 0 )
				{
					continue;
				}
				break;

			case TEST_PLAN_UNIT_TESTS:
				if( !unitTest )
				{
					continue;
				}
				break;

			case TEST_PLAN_VISUAL_TESTS:
				if( demoName.substr( demoName.indexOf('/')+1, 4 ) != "Test"  || unitTest )
				{
					continue;
				}
				break;

			default:
				break;
			}

			int offset = 0;
			int depth = 0;

			while( offset != -1 )
			{
				offset = demoName.indexOf('/');

				if( offset == -1 )
				{
					for ( int indent = 0; indent < depth; indent++ )
					{
						ostr.printf( "        " );
					}
					ostr.printf( "%s,\n", demoName.cString() );
				}
				else
				{
					hkString demoPath = demoName.substr(0, offset+1);

					if( depth >= demoPathItems.getSize() || demoPathItems[depth] != demoPath )
					{
						for ( int indent = 0; indent < depth; indent++ )
						{
							ostr.printf( "        " );
						}
						ostr.printf( "%s,\n", demoPath.cString() );

						int itemsToRemove = demoPathItems.getSize() - depth;
						for( int count = 0; count < itemsToRemove; count++ )
						{
							demoPathItems.popBack();
						}

						demoPathItems.pushBack( demoPath );
					}
					depth++;
					demoName = demoName.substr(offset+1);
				}
			}
		}
		m_step++;
	}

	if( m_step > 0 )
	{
		m_env->m_textDisplay->outputText(hkString( "Done. Output is in " ) + testPlanFilename, 20, 250, 0xffffffff);
	}

	return DEMO_OK;
}