예제 #1
0
FUBoundingSphere FUBoundingSphere::Transform(const FMMatrix44& transform) const
{
	if (!IsValid()) return (*this);

	FMVector3 transformedCenter = transform.TransformCoordinate(center);
	FUBoundingSphere transformedSphere(transformedCenter, 0.0f);

	// Calculate the transformed bounding sphere radius using three sample points.
	FMVector3 testPoints[3] =
	{
		FMVector3(radius, 0.0f, 0.0f),
		FMVector3(0.0f, radius, 0.0f),
		FMVector3(0.0f, 0.0f, radius)
	};

	for (size_t i = 0; i < 6; ++i)
	{
		testPoints[i] = transform.TransformVector(testPoints[i]);
		float lengthSquared = testPoints[i].LengthSquared();
		if (lengthSquared > transformedSphere.radius * transformedSphere.radius)
		{
			transformedSphere.radius = sqrtf(lengthSquared);
		}
	}

	return transformedSphere;
}
예제 #2
0
파일: PMDConvert.cpp 프로젝트: Marlinc/0ad
	/**
	 * Applies world-space transform to vertex data and transforms Collada's right-handed
	 *	Y-up / Z-up coordinates to the game's left-handed Y-up coordinate system
	 */
	static void TransformStaticModel(float* position, float* normal, size_t vertexCount,
		const FMMatrix44& transform, bool yUp)
	{
		for (size_t i = 0; i < vertexCount; ++i)
		{
			FMVector3 pos (&position[i*3], 0);
			FMVector3 norm (&normal[i*3], 0);

			// Apply the scene-node transforms
			pos = transform.TransformCoordinate(pos);
			norm = FMVector3_Normalize(transform.TransformVector(norm));

			// Convert from right-handed Y_UP or Z_UP to the game's coordinate system (left-handed Y-up)

			if (yUp)
			{
				pos.z = -pos.z;
				norm.z = -norm.z;
			}
			else
			{
				std::swap(pos.y, pos.z);
				std::swap(norm.y, norm.z);
			}

			// Copy back to array

			position[i*3] = pos.x;
			position[i*3+1] = pos.y;
			position[i*3+2] = pos.z;

			normal[i*3] = norm.x;
			normal[i*3+1] = norm.y;
			normal[i*3+2] = norm.z;
		}
	}
예제 #3
0
파일: PMDConvert.cpp 프로젝트: Marlinc/0ad
	/**
	 * Applies world-space transform to vertex data and transforms Collada's right-handed
	 *	Y-up / Z-up coordinates to the game's left-handed Y-up coordinate system
	 */
	static void TransformSkinnedModel(float* position, float* normal, size_t vertexCount,
		std::vector<BoneTransform>& bones, std::vector<PropPoint>& propPoints,
		const FMMatrix44& transform, const FMMatrix44& bindTransform, bool yUp, bool isXSI)
	{
		FMMatrix44 scaledTransform; // for vertexes
		FMMatrix44 scaleMatrix; // for bones

		// HACK: see comment in PSAConvert::TransformVertices
		if (isXSI)
		{
			scaleMatrix = DecomposeToScaleMatrix(transform);
			scaledTransform = DecomposeToScaleMatrix(bindTransform) * transform;
		}
		else
		{
			scaleMatrix = FMMatrix44_Identity;
			scaledTransform = bindTransform;
		}

		// Update the vertex positions and normals
		for (size_t i = 0; i < vertexCount; ++i)
		{
			FMVector3 pos (&position[i*3], 0);
			FMVector3 norm (&normal[i*3], 0);

			// Apply the scene-node transforms
			pos = scaledTransform.TransformCoordinate(pos);
			norm = FMVector3_Normalize(scaledTransform.TransformVector(norm));

			// Convert from right-handed Y_UP or Z_UP to the game's coordinate system (left-handed Y-up)

			if (yUp)
			{
				pos.z = -pos.z;
				norm.z = -norm.z;
			}
			else
			{
				std::swap(pos.y, pos.z);
				std::swap(norm.y, norm.z);
			}

			// and copy back into the original array

			position[i*3] = pos.x;
			position[i*3+1] = pos.y;
			position[i*3+2] = pos.z;

			normal[i*3] = norm.x;
			normal[i*3+1] = norm.y;
			normal[i*3+2] = norm.z;
		}

		TransformBones(bones, scaleMatrix, yUp);

		// And do the same for prop points
		for (size_t i = 0; i < propPoints.size(); ++i)
		{
			if (yUp)
			{
				propPoints[i].translation[0] = -propPoints[i].translation[0];
				propPoints[i].orientation[0] = -propPoints[i].orientation[0];
				propPoints[i].orientation[3] = -propPoints[i].orientation[3];
			}
			else
			{
				// Flip translation across the x-axis by swapping y and z
				std::swap(propPoints[i].translation[1], propPoints[i].translation[2]);

				// To convert the quaternions: imagine you're using the axis/angle
				// representation, then swap the y,z basis vectors and change the
				// direction of rotation by negating the angle ( => negating sin(angle)
				// => negating x,y,z => changing (x,y,z,w) to (-x,-z,-y,w)
				// but then (-x,-z,-y,w) == (x,z,y,-w) so do that instead)
				std::swap(propPoints[i].orientation[1], propPoints[i].orientation[2]);
				propPoints[i].orientation[3] = -propPoints[i].orientation[3];
			}
		}

	}