// Copyright (C) 2012 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include #include template NzVector4::NzVector4() { } template NzVector4::NzVector4(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) { } template NzVector4::NzVector4(T scale) : x(scale), y(scale), z(scale), w(scale) { } template NzVector4::NzVector4(T vec[4]) : x(vec[0]), y(vec[1]), z(vec[2]), w(vec[3]) { } template template NzVector4::NzVector4(const NzVector4& vec) : x(static_cast(vec.x)), y(static_cast(vec.y)), z(static_cast(vec.z)), w(static_cast(vec.w)) { } template T NzVector4::AbsDotProduct(const NzVector4& vec) const { return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z) + std::fabs(w * vec.w); } template<> inline int NzVector4::AbsDotProduct(const NzVector4& vec) const { return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w); } template T NzVector4::DotProduct(const NzVector4& vec) const { return x * vec.x + y * vec.y + z * vec.z + w * vec.w; } template void NzVector4::MakeCeil(const NzVector4& vec) { if (vec.x > x) x = vec.x; if (vec.y > y) y = vec.y; if (vec.z > z) z = vec.z; if (vec.w > w) w = vec.w; } template void NzVector4::MakeFloor(const NzVector4& vec) { if (vec.x < x) x = vec.x; if (vec.y < y) y = vec.y; if (vec.z < z) z = vec.z; if (vec.w < w) w = vec.w; } template void NzVector4::Normalize() { if (w != 0.f) { x /= w; y /= w; z /= w; } } template NzString NzVector4::ToString() const { NzStringStream ss; return ss << "Vector4(" << x << ", " << y << ", " << z <<')'; } template NzVector4::operator NzString() const { return ToString(); } template T& NzVector4::operator[](unsigned int i) { if (i >= 4) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)"; throw std::domain_error(ss.ToString()); } return *(&x+i); } template T NzVector4::operator[](unsigned int i) const { if (i >= 4) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 4)"; throw std::domain_error(ss.ToString()); } return *(&x+i); } template const NzVector4& NzVector4::operator+() const { return *this; } template NzVector4 NzVector4::operator-() const { return NzVector4(-x, -y, -z, -w); } template NzVector4 NzVector4::operator+(const NzVector4& vec) const { return NzVector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w); } template NzVector4 NzVector4::operator-(const NzVector4& vec) const { return NzVector4(x - vec.x, y - vec.y, z - vec.z); } template NzVector4 NzVector4::operator*(const NzVector4& vec) const { return NzVector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w); } template NzVector4 NzVector4::operator*(T scale) const { return NzVector4(x * scale, y * scale, z * scale, w * scale); } template NzVector4 NzVector4::operator/(const NzVector4& vec) const { if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; throw std::domain_error(ss.ToString()); } return NzVector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w); } template NzVector4 NzVector4::operator/(T scale) const { if (scale == 0.f) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; throw std::domain_error(ss.ToString()); } return NzVector4(x / scale, y / scale, z / scale, w / scale); } template NzVector4& NzVector4::operator+=(const NzVector4& vec) { x += vec.x; y += vec.y; z += vec.z; w += vec.w; return *this; } template NzVector4& NzVector4::operator-=(const NzVector4& vec) { x -= vec.x; y -= vec.y; z -= vec.z; w -= vec.w; return *this; } template NzVector4& NzVector4::operator*=(const NzVector4& vec) { x *= vec.x; y *= vec.y; z *= vec.z; w *= vec.w; return *this; } template NzVector4& NzVector4::operator*=(T scale) { x *= scale; y *= scale; z *= scale; w *= scale; return *this; } template NzVector4& NzVector4::operator/=(const NzVector4& vec) { if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; throw std::domain_error(ss.ToString()); } x /= vec.x; y /= vec.y; z /= vec.z; w /= vec.w; return *this; } template NzVector4& NzVector4::operator/=(T scale) { if (scale == 0.f) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; throw std::domain_error(ss.ToString()); } x /= scale; y /= scale; z /= scale; w /= scale; return *this; } template bool NzVector4::operator==(const NzVector4& vec) const { return NzNumberEquals(x, vec.x) && NzNumberEquals(y, vec.y) && NzNumberEquals(z, vec.z) && NzNumberEquals(w, vec.w); } template bool NzVector4::operator!=(const NzVector4& vec) const { return !operator==(vec); } template bool NzVector4::operator<(const NzVector4& vec) const { return x < vec.x && y < vec.y && z < vec.z && w < vec.w; } template bool NzVector4::operator<=(const NzVector4& vec) const { return operator<(vec) || operator==(vec); } template bool NzVector4::operator>(const NzVector4& vec) const { return !operator<=(vec); } template bool NzVector4::operator>=(const NzVector4& vec) const { return !operator<(vec); } template std::ostream& operator<<(std::ostream& out, const NzVector4& vec) { return out << vec.ToString(); } template NzVector4 operator*(T scale, const NzVector4& vec) { return NzVector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); } template NzVector4 operator/(T scale, const NzVector4& vec) { if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; throw std::domain_error(ss.ToString()); } return NzVector4(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w); } #include