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; }