hkUint16 DestructibleHierarchy::getLookupIndexOfNewDestructibleNode(DestructibleHierarchy* hierarchy, int nodeIdxInDestructibleHierarchy)
{
	HK_ASSERT2(0xad678bad, s_nodeInfos, "Array not created.");
	if (s_nodeInfos->isEmpty())
	{
		// dummy node, so that index of valid nodes in non-zero
		s_nodeInfos->expandOne();
	}

	unsigned int lookupIdx = s_nodeInfos->getSize();

	NodeInformation& info = s_nodeInfos->expandOne();
	info.m_destructibleHierarchy = hierarchy;
	info.m_nodeIdx = nodeIdxInDestructibleHierarchy;
	HK_ASSERT2(0xad6288dd, s_nodeInfos->getSize() <= (1<<16), "Too many destructible nodes in the lookup table -- we only have 16 bits for the index into the table" );

	return hkUint16(lookupIdx);
}
Esempio n. 2
0
hkpMoppBvTreeShape* RoundTrackDemo::createMoppShape()
{
	//
	// Create the vertices (a "heightfield" of triangles)
	//
	{
		const float borderHeight = 5.0f;
		const hkReal radius = 500.0f;
		const hkReal width = 55.0f;
		const hkReal jumps = 0.15f;
		const hkReal bendsFrequency  = 10.0f;
		const hkReal bendsSize = 60.0f;
		{
			for(int i = 0; i < SIDEA; i++)
			{
				for (int j = 0; j < SIDEB; j++ )
				{

					float h = (hkMath::cos(0.2f*((hkReal)j + i)) + 0.5f * hkMath::sin( 0.2f*2.0f * i));
					h = h * h * h * h *h * h - 6;
					h *= jumps;

					//
					//	Now bend the track in a circle
					//
					hkReal angle = i / float(SIDEA) * 6.32f;
					float si = hkMath::sin( angle );
					float co = hkMath::cos( angle );

					int j2 = j-1; if ( j2<0 ) j2++;
					if ( j2 >= SIDEB - 2) j2--;

					float sj = j2 / float(SIDEB - 2);

					float bends = bendsSize * hkMath::sin( angle * bendsFrequency ) * hkMath::sin( angle * bendsFrequency * 0.34f ); 
					float x = si * (radius + sj * width + bends) + radius;
					float y = co * (radius + sj * width + bends);

					m_vertices[(i * SIDEB + j) * 3  + 0] = x;
					m_vertices[(i * SIDEB + j) * 3  + 1] = h;
					m_vertices[(i * SIDEB + j) * 3  + 2] = y;
				}
			}
		}
		//
		//	Add a border
		//
		{
			for(int i = 0; i < SIDEA; i++)
			{
				m_vertices[ (i * SIDEB + 0     ) * 3  + 1] = borderHeight;
				m_vertices[ (i * SIDEB + SIDEB-1) * 3  + 1] = borderHeight;
			}

		}
	}

	//
	// Create the triangles
	//
	{
		hkUint16 corner = 0;
		int index = 0;
		for(int i = 0; i < SIDEA - 1; i++)
		{
			for (int j = 0; j < SIDEB - 1; j++ )
			{
				m_indices[index]     = hkUint16(corner);
				m_indices[index + 1] = hkUint16(corner + 1);
				m_indices[index + 2] = hkUint16(corner + SIDEB);

				m_indices[index + 3] = hkUint16(corner + 1);
				m_indices[index + 4] = hkUint16(corner + SIDEB);
				m_indices[index + 5] = hkUint16(corner + SIDEB + 1);

				index += 6;
				corner++; 
			}
			corner++; 
		}
	}

	hkpMeshShape* meshShape = new hkpFastMeshShape( );
	meshShape->setRadius(0.05f);
	{
		hkpMeshShape::Subpart part;

		part.m_vertexBase = m_vertices;
		part.m_vertexStriding = sizeof(float) * 3;
		part.m_numVertices = NUM_VERTICES;

		part.m_indexBase = m_indices;
		part.m_indexStriding = sizeof( hkUint16 ) * 3;
		part.m_numTriangles = NUM_TRIANGLES;
		part.m_stridingType = hkpMeshShape::INDICES_INT16;

		meshShape->addSubpart( part );
	}

	hkpMoppCompilerInput mci;
	hkpMoppCode* code = hkpMoppUtility::buildCode( meshShape , mci);

	hkpMoppBvTreeShape* moppShape = new hkpMoppBvTreeShape(meshShape, code);
	code->removeReference();
	meshShape->removeReference();

	return moppShape;
}
Esempio n. 3
0
void FlatLand::setupVertexAndTriangleData()
{
	//
	// Create the vertices (a "heightfield" of triangles)
	//
	{
		const float borderHeight = getBorderHeight();
		{
			for(int i = 0; i < m_side; i++)
			{
				for (int j = 0; j < m_side; j++ )
				{ 

					float h = getHeight( i, j );

					m_vertices[(i * m_side + j) * 4  + 0] = i * 1.0f - m_side * 0.5f;
					m_vertices[(i * m_side + j) * 4  + 1] = h;
					m_vertices[(i * m_side + j) * 4  + 2] = j * 1.0f - m_side * 0.5f;
					m_vertices[(i * m_side + j) * 4  + 3] = 0.0f;	// we need to set this to avoid denormals on P4
				}
			}
		}
		//
		//	Add a border
		//
		{
			for(int i = 0; i < m_side; i++)
			{
				m_vertices[ (          i * m_side + 0     ) * 4  + 1] = borderHeight;
				m_vertices[ (          i * m_side + m_side-1) * 4  + 1] = borderHeight;
				m_vertices[ ( (m_side-1) * m_side + i       ) * 4  + 1] = borderHeight;
				m_vertices[ (i                ) * 4  + 1] = borderHeight;
			}
		}
	}

	//
	// Create the triangles
	//
	{
		hkUint16 corner = 0;
		int index = 0;
		for(int i = 0; i < m_side - 1; i++)
		{
			for (int j = 0; j < m_side - 1; j++ )
			{
				m_indices[index]     = hkUint16(corner);
				m_indices[index + 1] = hkUint16(corner + 1);
				m_indices[index + 2] = hkUint16(corner + m_side);
				// m_indices[index + 3] Dummy

				m_indices[index + 4] = hkUint16(corner + 1);
				m_indices[index + 5] = hkUint16(corner + m_side + 1);
				m_indices[index + 6] = hkUint16(corner + m_side);
				// m_indices[index + 7] Dummy

				index += 8;
				corner++; 
			}
			corner++; 
		}
	}
}
Esempio n. 4
0
void TowerLand::setupVertexAndTriangleData()
{
	//
	// Create the vertices (a "heightfield" of triangles)
	//
	{
		const float borderHeight = getBorderHeight();
		{
			for(int i = 0; i < m_side; i++)
			{
				for (int j = 0; j < m_side; j++ )
				{ 

					float h = getHeight( i, j );

					m_vertices[ (i * m_side + j) * 4  + 0 ] = ((i - m_side * 0.5f) / m_side) * m_size;
					m_vertices[ (i * m_side + j) * 4  + 1 ] = h;
					m_vertices[ (i * m_side + j) * 4  + 2 ] = ((j - m_side * 0.5f) / m_side) * m_size - ( (i%2) * m_shift);
					m_vertices[ (i * m_side + j) * 4  + 3 ] = 0.0f;	// we need to set this to avoid denormals on P4
				}
			}
		}
		//
		//	Add a border
		//
		{
			for(int i = 0; i < m_side; i++)
			{
				m_vertices[ (i * m_side + 0     )                 * 4  + 1] = borderHeight;
				m_vertices[ (i * m_side + m_side-1)               * 4  + 1] = borderHeight;
				m_vertices[ ( (m_side-1) * (m_side-1) + i       ) * 4  + 1] = borderHeight;
				m_vertices[ (i                                  ) * 4  + 1] = borderHeight;
			}
		}
	}

	//
	// Create the triangles
	//
	{
		hkUint16 corner = 0;
		int index = 0;
		for(int i = 0; i < m_side - 1; i++)
		{
			for (int j = 0; j < m_side - 1; j++ )
			{
				m_indices[index]     = hkUint16(corner);
				m_indices[index + 1] = hkUint16(corner + 1);
				m_indices[index + 2] = hkUint16(corner + m_side);
				m_indices[index + 3] = 0; // padding needed for spus

				m_indices[index + 4] = hkUint16(corner + 1);
				m_indices[index + 5] = hkUint16(corner + m_side + 1);
				m_indices[index + 6] = hkUint16(corner + m_side);
				m_indices[index + 7] = 0; // padding needed for spus

				index += 8;
				corner++; 
			}
			corner++; 
		}
	}
}
Esempio n. 5
0
void hkFlattenShapeHierarchyUtil::getLeafShapesFromShape(const hkpShape* shape, const hkTransform& transform, const hkBool isFixedBody, hkArray<hkpExtendedMeshShape::TrianglesSubpart>& trianglePartsOut, hkArray<hkpConvexShape*>& convexShapesOut, hkArray<hkpShape*>& otherShapesOut)
{
	const hkpShapeType type = shape->getType();

	hkTransform newTransform;

	const hkpShape* childShape = HK_NULL;
	hkUlong userData = HK_NULL;

	switch(type)
	{
	case HK_SHAPE_LIST:
	case HK_SHAPE_CONVEX_LIST:
		{
			const hkpShapeContainer* container = shape->getContainer();
			hkpShapeContainer::ShapeBuffer buffer;

			HK_ASSERT2(0xad67da22, 0 == (0xffff0000 & hkUlong(shape->getUserData())), "We're dropping a non-zero lookupIndex from user data.");
			hkUint16 materialId = hkUint16(0xffff & hkUlong(shape->getUserData()));

			for (hkpShapeKey key = container->getFirstKey(); key != HK_INVALID_SHAPE_KEY; key = container->getNextKey(key))
			{
				const hkpShape* child = container->getChildShape(key, buffer);

				if (materialId && 0 == (0xffff & hkUlong(child->getUserData())) )
				{
					// no material id for the child -- copy it
					hkUlong childData = hkUlong(child->getUserData()) | materialId;
					// Warning: modifying the const input hkpShape*
					const_cast<hkpShape*>(child)->setUserData(childData);
				}
				//HK_ASSERT2(0xad6777dd, isFixedBody || !isLeafShape(child), "A child of a list shape cannot be a terminal node. You must use a transform shape in between." );
				getLeafShapesFromShape(child, transform, isFixedBody, trianglePartsOut, convexShapesOut, otherShapesOut);
			}
		}
		break;
	case HK_SHAPE_TRANSFORM:
		{
			const hkpTransformShape* transformShape = static_cast<const hkpTransformShape*>(shape);
			newTransform.setMul(transform, transformShape->getTransform());
			childShape = transformShape->getChildShape();
			userData = hkUlong(transformShape->getUserData());
		}
		break;
	case HK_SHAPE_CONVEX_TRANSFORM:
		{
			const hkpConvexTransformShape* convexTransformShape = static_cast<const hkpConvexTransformShape*>(shape);
			newTransform.setMul(transform, convexTransformShape->getTransform());
			childShape = convexTransformShape->getChildShape();
			userData = hkUlong(convexTransformShape->getUserData());
		}
		break;
	case HK_SHAPE_CONVEX_TRANSLATE:
		{
			const hkpConvexTranslateShape* convexTranslateShape = static_cast<const hkpConvexTranslateShape*>(shape);
			hkTransform localTransform( static_cast<const hkRotation&>(hkRotation::getIdentity()), convexTranslateShape->getTranslation() );
			newTransform.setMul(transform, localTransform);
			childShape = convexTranslateShape->getChildShape();
			userData = hkUlong(convexTranslateShape->getUserData());
		}
		break;

	case HK_SHAPE_BV_TREE:
		{
			const hkpBvTreeShape* bvTreeshape = static_cast<const hkpBvTreeShape*>(shape);	
			HK_ASSERT2(0xad67da22, 0 == (0xffff0000 & hkUlong(bvTreeshape->getUserData())), "We're dropping a non-zero lookupIndex from user data.");

			const hkpShapeContainer* container = bvTreeshape->getContainer();
			for (hkpShapeKey key = container->getFirstKey(); key!= HK_INVALID_SHAPE_KEY; key = container->getNextKey(key))
			{
				hkpShapeContainer::ShapeBuffer buffer;
				const hkpShape* child = container->getChildShape(key, buffer);
				const hkpShapeType childType = child->getType();
				if ((childType == HK_SHAPE_LIST) || (childType == HK_SHAPE_CONVEX_LIST))
				{
					getLeafShapesFromShape(child, transform, isFixedBody, trianglePartsOut, convexShapesOut, otherShapesOut);
				}
			}

			break;
		}
	case HK_SHAPE_MOPP:
		{
			const hkpMoppBvTreeShape* bvTreeshape = static_cast<const hkpMoppBvTreeShape*>(shape);	
		//	HK_ASSERT2(0xad67da22, 0 == (0xffff0000 & hkUlong(bvTreeshape->getUserData())), "We're dropping a non-zero lookupIndex from user data.");
			getLeafShapesFromShape(bvTreeshape->getShapeCollection(), transform, isFixedBody, trianglePartsOut, convexShapesOut, otherShapesOut);

			break;
		}

	default:
		{
			//HK_ASSERT2(0xad67ddaa, isFixedBody, "A child of a list was attached without an intermediate transform shape. This is not handled.");
			
			// We can get simple shapes without transforms when processing fixed bodies. We do add a hkpConvexTransformShape as usual then ...
			childShape = shape;
			newTransform = transform;
			userData = hkUlong(shape->getUserData());
			//HK_ASSERT2(0XAD678D8D, 0 == (userData & 0xffff0000), "Userdata of a fixed body (other than the one fixed uber body) has a non-zero destructible info index.");
		}
		break;
	}

	if (HK_NULL != childShape)
	{
		hkBool leafDone = false;
		if (hkOneFixedMoppUtil::isTerminalConvexShape(childShape))
		{
			// Create new transform shape to wrap the child terminal shape
			hkpConvexTransformShape* newConvexTransformShape = new hkpConvexTransformShape(static_cast<const hkpConvexShape*>(childShape), newTransform);
			newConvexTransformShape->setUserData( userData );

			HK_ASSERT2(0xad67da23, 0 == (0xffff0000 & hkUlong(childShape->getUserData())) || (0xffff0000 & userData) == (0xffff0000 & hkUlong(childShape->getUserData())), "We're dropping a non-zero user data.");
			HK_ASSERT2(0xad67da24, 0 == (0xffff & hkUlong(childShape->getUserData())) || (0xffff & userData) == (0xffff & hkUlong(childShape->getUserData())), "Materials differ in the terminal shape and its wrapping hkpTransformShape.");

			// put this transform on the shapesOut list
			convexShapesOut.pushBack(newConvexTransformShape);
			leafDone = true;
		}
		else if (isLeafShape(childShape))
		{
				// It's not a terminal(leaf?) convex shape, but it might be a mesh, or indeed a simplemesh.
				// It's most likely to be a storagemesh, but we can't assume that, so check vtable:
			const hkClass* childShapeClass = hkBuiltinTypeRegistry::getInstance().getVtableClassRegistry()->getClassFromVirtualInstance(childShape);
			if( hkpMeshShapeClass.isSuperClass(*childShapeClass) )
			{
				const hkpMeshShape* mesh = static_cast<const hkpMeshShape*>(childShape);

				// Confirm vertex data not shared, see below
#if defined(HK_DEBUG)
				{
					for(int i = 0; i < mesh->getNumSubparts(); i++)
					{
						const hkpMeshShape::Subpart& meshSubPartI = mesh->getSubpartAt(i);
						for(int j = i+1; j < mesh->getNumSubparts(); j++)
						{
							const hkpMeshShape::Subpart& meshSubPartJ = mesh->getSubpartAt(j);
							HK_ASSERT2(0x0, meshSubPartI.m_vertexBase != meshSubPartJ.m_vertexBase, "This method can't (currently) collapse chared meshs data as it collpases the transform into the verts\n");
						}
						
					}
				}
#endif

				for(int i = 0; i < mesh->getNumSubparts(); i++)
				{
					const hkpMeshShape::Subpart& meshSubPart = mesh->getSubpartAt(i);
					// Now we have the subpart. We can't know if the data pointed to is 'owned' by the mesh (eg. subclass hkpStorageMeshShape)
					// or 'pointed to' (base class hkpMeshShape)
					//
					// We'll just assume here we can 'share' the data by grabbing the pointers...

					hkpExtendedMeshShape::TrianglesSubpart extendedMeshSubPart;
					
					extendedMeshSubPart.m_vertexBase = meshSubPart.m_vertexBase;
					extendedMeshSubPart.m_vertexStriding = meshSubPart.m_vertexStriding;
					extendedMeshSubPart.m_numVertices = meshSubPart.m_numVertices;
					extendedMeshSubPart.m_triangleOffset = meshSubPart.m_triangleOffset;

					// .. but we'll have to multiply in the transform! This assumes the vertex data is not shared!
					{
						for(int j = 0; j < extendedMeshSubPart.m_numVertices ; j++)
						{
							hkVector4 v;
							v(0) = extendedMeshSubPart.m_vertexBase[0 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j];
							v(1) = extendedMeshSubPart.m_vertexBase[1 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j];
							v(2) = extendedMeshSubPart.m_vertexBase[2 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j];
							v.setTransformedPos(transform, v);
							const_cast<float*>(extendedMeshSubPart.m_vertexBase)[0 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j] = v(0);
							const_cast<float*>(extendedMeshSubPart.m_vertexBase)[1 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j] = v(1);
							const_cast<float*>(extendedMeshSubPart.m_vertexBase)[2 + extendedMeshSubPart.m_vertexStriding/sizeof(float) * j] = v(2);
						}
					}

					extendedMeshSubPart.m_indexBase = meshSubPart.m_indexBase;
					extendedMeshSubPart.m_indexStriding = meshSubPart.m_indexStriding;
					extendedMeshSubPart.m_numTriangleShapes = meshSubPart.m_numTriangles;
					extendedMeshSubPart.m_stridingType = (meshSubPart.m_stridingType == hkpMeshShape::INDICES_INT16) ? hkpExtendedMeshShape::INDICES_INT16 : hkpExtendedMeshShape::INDICES_INT32;

					trianglePartsOut.pushBack(extendedMeshSubPart);

					leafDone = true;
				}
			}
		}

		if(!leafDone)
		{
			HK_WARN(0xad678dda, "An extra hkTransform shape has been inserted into the hierarchy. This might be suboptimal.");
			// Create new transform shape to wrap the child terminal shape
			hkpTransformShape* newTransformShape = new hkpTransformShape(childShape, newTransform);
			newTransformShape->setUserData( userData );

			HK_ASSERT2(0xad67da23, 0 == (0xffff0000 & hkUlong(childShape->getUserData())) || (0xffff0000 & userData) == (0xffff0000 & hkUlong(childShape->getUserData())), "We're dropping a non-zero user data.");
			HK_ASSERT2(0xad67da24, 0 == (0xffff & hkUlong(childShape->getUserData())) || (0xffff & userData) == (0xffff & hkUlong(childShape->getUserData())), "Materials differ in the terminal shape and its wrapping hkpTransformShape.");

			// put this transform on the shapesOut list
			otherShapesOut.pushBack(newTransformShape);
			leafDone = true;
		}

		if(!leafDone)
		{
			//HK_ASSERT2(0xad67da23, 0 == (0xffff0000 & shape->getUserData()), "We're dropping a non-zero user data.");
			if ( 0xffff0000 & hkUlong(shape->getUserData()) )
			{
				// copy the destruction info index downwards..
				HK_ASSERT2(0xad67da23, 0 == (0xffff0000 & hkUlong(childShape->getUserData())) || (0xffff0000 & userData) == (0xffff0000 & hkUlong(childShape->getUserData())), "We're dropping a non-zero user data.");
				HK_ASSERT2(0xad67da24, 0 == (0xffff & hkUlong(childShape->getUserData())) || (0xffff & hkUlong(shape->getUserData())) == (0xffff & hkUlong(childShape->getUserData())), "Materials differ in the terminal shape and its wrapping hkpTransformShape.");

				//HK_WORLD_ACCESS_CHECK(parentBody->getWorld(), HK_ACCESS_RW );
				// Warning: we're actually modifying the const hkpShape* passed as an input parameter
				const_cast<hkpShape*>(childShape)->setUserData( shape->getUserData() );
			}
			getLeafShapesFromShape(childShape, newTransform, isFixedBody, trianglePartsOut, convexShapesOut, otherShapesOut);
		}
	}
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
0
		// Generate a rough terrain
		HK_FORCE_INLINE hkReal getHeightAtImpl(int x, int z) const {
			// Lookup data and return a float
			// We scale the data artifically by 5 to make it look interesting
			return hkReal(m_data[x * m_zRes + z]) / hkReal(hkUint16(-1)) * 2048.0f - 1024.0f;
		}