Beispiel #1
0
void Cone::RotateAngularDirection(float radians)
{
	GfxTL::Quaternion< float > q;
	q.RotationRad(radians, m_axisDir[0], m_axisDir[1], m_axisDir[2]);
	Vec3f vvec;
	q.Rotate(AngularDirection(), &vvec);
	m_hcs[0] = GfxTL::Vector3Df(vvec);
	m_hcs[1] = GfxTL::Vector3Df(m_axisDir.cross(Vec3f(m_hcs[0].Data())));
	m_angularRotatedRadians += radians;
}
bool CylinderPrimitiveShape::InSpace(float u, float v, Vec3f *p, Vec3f *n) const
{
	GfxTL::Quaternion< float > q;
	q.RotationRad(v / m_cylinder.Radius(), m_cylinder.AxisDirection()[0],
		m_cylinder.AxisDirection()[1], m_cylinder.AxisDirection()[2]);
	Vec3f vvec;
	q.Rotate(m_cylinder.AngularDirection(), &vvec);
	*p = u * m_cylinder.AxisDirection() + m_cylinder.Radius() * vvec
		+ m_cylinder.AxisPosition();
	*n = vvec;
	return true;
}
bool CylinderPrimitiveShape::InSpace(size_t u, size_t v, float epsilon,
	const GfxTL::AABox< GfxTL::Vector2Df > &bbox, size_t uextent,
	size_t vextent, Vec3f *p, Vec3f *n) const
{
	GfxTL::Quaternion< float > q;
	q.RotationRad((bbox.Min()[1] + epsilon * (v + .5f)) / m_cylinder.Radius(),
		m_cylinder.AxisDirection()[0],
		m_cylinder.AxisDirection()[1],
		m_cylinder.AxisDirection()[2]);
	Vec3f vvec;
	q.Rotate(m_cylinder.AngularDirection(), &vvec);
	*p = (bbox.Min()[0] + epsilon * (u + .5f)) * m_cylinder.AxisDirection() +
		m_cylinder.Radius() * vvec + m_cylinder.AxisPosition();
	*n = vvec;
	return true;
}
bool ConePrimitiveShape::InSpace(size_t u, size_t v, float epsilon,
	const GfxTL::AABox< GfxTL::Vector2Df > &bbox, size_t uextent,
	size_t vextent, Vec3f *p, Vec3f *n) const
{
	float length, angle;
	if(m_cone.Angle() >= float(M_PI / 4))
	{
		float uf = ((float(u) + .5f) * epsilon) + bbox.Min()[0];
		float vf = ((float(v) + .5f) * epsilon) + bbox.Min()[1];
		length = std::sqrt(uf * uf + vf * vf);
		//angle = std::atan2(vf, uf);
		angle = std::atan2(uf, vf);
		//angle = std::acos(GfxTL::Math< float >::Clamp(vf / length, -1.f, 1.f));
	}
	else
	{
		length = ((float(u) + .5f) * epsilon) + bbox.Min()[0];
		float arcLength = ((float(v) + .5f) * epsilon) + bbox.Min()[1];
		angle = (arcLength / m_cone.RadiusAtLength(length)) + float(M_PI);
	}
	if(angle > 2 * float(M_PI))
		return false;
	//float angle = ((v * epsilon) / m_cone.RadiusAtLength(std::max(abs(bbox.Min()[0]), abs(bbox.Max()[0])))
	//	+ bbox.Min()[1]);
	GfxTL::Quaternion< float > q;
	q.RotationRad(angle, m_cone.AxisDirection()[0],
		m_cone.AxisDirection()[1], m_cone.AxisDirection()[2]);
	Vec3f vvec;
	q.Rotate(m_cone.AngularDirection(), &vvec);
	*p = std::sin(m_cone.Angle()) * abs(length) * vvec +
		std::cos(m_cone.Angle()) * length * m_cone.AxisDirection() +
		m_cone.Center();
	// TODO: this is very lazy and should be optimized!
	m_cone.Normal(*p, n);
	return true;
}
bool ConePrimitiveShape::InSpace(float length, float arcLength, Vec3f *p,
	Vec3f *n) const
{
	float angle;
	if(m_cone.Angle() >= float(M_PI / 4))
	{
		//angle = std::atan2(arcLength, length);
		angle = std::atan2(length, arcLength);
		length = std::sqrt(length * length + arcLength * arcLength);
//		angle = std::acos(GfxTL::Math< float >::Clamp(arcLength / length, -1.f, 1.f));
	}
	else
		angle = (arcLength / m_cone.RadiusAtLength(length)) + float(M_PI);
	GfxTL::Quaternion< float > q;
	q.RotationRad(angle, m_cone.AxisDirection()[0],
		m_cone.AxisDirection()[1], m_cone.AxisDirection()[2]);
	Vec3f vvec;
	q.Rotate(m_cone.AngularDirection(), &vvec);
	*p = std::sin(m_cone.Angle()) * abs(length) * vvec +
		std::cos(m_cone.Angle()) * length * m_cone.AxisDirection() +
		m_cone.Center();
	m_cone.Normal(*p, n);
	return true;
}