diff --git a/src/nvimage/ColorBlock.cpp b/src/nvimage/ColorBlock.cpp index 9f18edf..2da7752 100644 --- a/src/nvimage/ColorBlock.cpp +++ b/src/nvimage/ColorBlock.cpp @@ -5,6 +5,7 @@ #include "FloatImage.h" #include "nvmath/Box.h" +#include "nvmath/Vector.inl" #include "nvcore/Utils.h" // swap #include // memcpy diff --git a/src/nvimage/ColorBlock.h b/src/nvimage/ColorBlock.h index 572be5a..054bb61 100644 --- a/src/nvimage/ColorBlock.h +++ b/src/nvimage/ColorBlock.h @@ -5,6 +5,7 @@ #define NV_IMAGE_COLORBLOCK_H #include "nvmath/Color.h" +#include "nvmath/Vector.h" namespace nv { diff --git a/src/nvimage/ErrorMetric.cpp b/src/nvimage/ErrorMetric.cpp index e9e8bc3..06c1ea1 100644 --- a/src/nvimage/ErrorMetric.cpp +++ b/src/nvimage/ErrorMetric.cpp @@ -4,6 +4,7 @@ #include "Filter.h" #include "nvmath/Matrix.h" +#include "nvmath/Vector.inl" #include // FLT_MAX diff --git a/src/nvimage/FloatImage.cpp b/src/nvimage/FloatImage.cpp index f0405b9..57e8dba 100644 --- a/src/nvimage/FloatImage.cpp +++ b/src/nvimage/FloatImage.cpp @@ -5,6 +5,7 @@ #include "Image.h" #include "nvmath/Color.h" +#include "nvmath/Vector.inl" #include "nvmath/Matrix.h" #include "nvcore/Utils.h" // max diff --git a/src/nvimage/NormalMap.cpp b/src/nvimage/NormalMap.cpp index 7461a80..e0b1092 100644 --- a/src/nvimage/NormalMap.cpp +++ b/src/nvimage/NormalMap.cpp @@ -26,7 +26,7 @@ #include "FloatImage.h" #include "Image.h" -#include "nvmath/Color.h" +#include "nvmath/Color.inl" #include "nvcore/Ptr.h" diff --git a/src/nvimage/Quantize.cpp b/src/nvimage/Quantize.cpp index a3d87e5..64168c8 100644 --- a/src/nvimage/Quantize.cpp +++ b/src/nvimage/Quantize.cpp @@ -17,6 +17,7 @@ http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT #include "PixelFormat.h" #include "nvmath/Color.h" +#include "nvmath/Vector.inl" #include "nvcore/Utils.h" // swap diff --git a/src/nvmath/Box.cpp b/src/nvmath/Box.cpp index ab2d771..7368f3c 100644 --- a/src/nvmath/Box.cpp +++ b/src/nvmath/Box.cpp @@ -1,7 +1,8 @@ // This code is in the public domain -- castanyo@yahoo.es -#include "nvmath/Box.h" -#include "nvmath/Sphere.h" +#include "Box.h" +#include "Box.inl" +//#include "Sphere.h" using namespace nv; @@ -25,6 +26,6 @@ float nv::distanceSquared(const Box &box, const Vector3 &point) { return lengthSquared(point - closest); } -bool nv::overlap(const Box &box, const Sphere &sphere) { +/*bool nv::overlap(const Box &box, const Sphere &sphere) { return distanceSquared(box, sphere.center) < sphere.radius * sphere.radius; -} +}*/ diff --git a/src/nvmath/Box.h b/src/nvmath/Box.h index f9aa458..dcbfd39 100644 --- a/src/nvmath/Box.h +++ b/src/nvmath/Box.h @@ -10,141 +10,67 @@ namespace nv { + class Vector; class Stream; class Sphere; - /// Axis Aligned Bounding Box. + // Axis Aligned Bounding Box. class Box { public: - /// Default ctor. - Box() { }; + Box(); + Box(const Box & b); + Box(const Vector3 & mins, const Vector3 & maxs); - /// Copy ctor. - Box(const Box & b) : minCorner(b.minCorner), maxCorner(b.maxCorner) { } + Box & operator=(const Box & b); - /// Init ctor. - Box(Vector3::Arg mins, Vector3::Arg maxs) : minCorner(mins), maxCorner(maxs) { } + operator const float * () const { return reinterpret_cast(this); } - // Assignment operator. - Box & operator=(const Box & b) { minCorner = b.minCorner; maxCorner = b.maxCorner; return *this; } + // Clear the bounds. + void clearBounds(); - // Cast operators. - operator const float * () const { return reinterpret_cast(this); } + // Build a cube centered on center and with edge = 2*dist + void cube(const Vector3 & center, float dist); + + // Build a box, given center and extents. + void setCenterExtents(const Vector3 & center, const Vector3 & extents); + + // Get box center. + Vector3 center() const; + + // Return extents of the box. + Vector3 extents() const; + + // Return extents of the box. + scalar extents(uint axis) const; - /// Clear the bounds. - void clearBounds() - { - minCorner.set(FLT_MAX, FLT_MAX, FLT_MAX); - maxCorner.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); - } - - /// Build a cube centered on center and with edge = 2*dist - void cube(Vector3::Arg center, float dist) - { - setCenterExtents(center, Vector3(dist, dist, dist)); - } - - /// Build a box, given center and extents. - void setCenterExtents(Vector3::Arg center, Vector3::Arg extents) - { - minCorner = center - extents; - maxCorner = center + extents; - } - - /// Get box center. - Vector3 center() const - { - return (minCorner + maxCorner) * 0.5f; - } - - /// Return extents of the box. - Vector3 extents() const - { - return (maxCorner - minCorner) * 0.5f; - } - - /// Return extents of the box. - scalar extents(uint axis) const - { - nvDebugCheck(axis < 3); - if (axis == 0) return (maxCorner.x - minCorner.x) * 0.5f; - if (axis == 1) return (maxCorner.y - minCorner.y) * 0.5f; - if (axis == 2) return (maxCorner.z - minCorner.z) * 0.5f; - nvAssume(false); - return 0.0f; - } - - /// Add a point to this box. - void addPointToBounds(Vector3::Arg p) - { - minCorner = min(minCorner, p); - maxCorner = max(maxCorner, p); - } - - /// Add a box to this box. - void addBoxToBounds(const Box & b) - { - minCorner = min(minCorner, b.minCorner); - maxCorner = max(maxCorner, b.maxCorner); - } - - /// Translate box. - void translate(Vector3::Arg v) - { - minCorner += v; - maxCorner += v; - } - - /// Scale the box. - void scale(float s) - { - minCorner *= s; - maxCorner *= s; - } + // Add a point to this box. + void addPointToBounds(const Vector3 & p); + + // Add a box to this box. + void addBoxToBounds(const Box & b); + + // Translate box. + void translate(const Vector3 & v); + + // Scale the box. + void scale(float s); // Expand the box by a fixed amount. - void expand(float r) { - minCorner -= Vector3(r,r,r); - maxCorner += Vector3(r,r,r); - } - - /// Get the area of the box. - float area() const - { - const Vector3 d = extents(); - return 8.0f * (d.x*d.y + d.x*d.z + d.y*d.z); - } - - /// Get the volume of the box. - float volume() const - { - Vector3 d = extents(); - return 8.0f * (d.x * d.y * d.z); - } - - /// Return true if the box contains the given point. - bool contains(Vector3::Arg p) const - { - return - minCorner.x < p.x && minCorner.y < p.y && minCorner.z < p.z && - maxCorner.x > p.x && maxCorner.y > p.y && maxCorner.z > p.z; - } - - /// Split the given box in 8 octants and assign the ith one to this box. - void setOctant(const Box & box, Vector3::Arg center, int i) - { - minCorner = box.minCorner; - maxCorner = box.maxCorner; - - if (i & 4) minCorner.x = center.x; - else maxCorner.x = center.x; - if (i & 2) minCorner.y = center.y; - else maxCorner.y = center.y; - if (i & 1) minCorner.z = center.z; - else maxCorner.z = center.z; - } + void expand(float r); + + // Get the area of the box. + float area() const; + + // Get the volume of the box. + float volume() const; + + // Return true if the box contains the given point. + bool contains(const Vector3 & p) const; + + // Split the given box in 8 octants and assign the ith one to this box. + void setOctant(const Box & box, const Vector3 & center, int i); friend Stream & operator<< (Stream & s, Box & box); diff --git a/src/nvmath/Box.inl b/src/nvmath/Box.inl new file mode 100644 index 0000000..33623e9 --- /dev/null +++ b/src/nvmath/Box.inl @@ -0,0 +1,142 @@ +// This code is in the public domain -- castanyo@yahoo.es + +#pragma once +#ifndef NV_MATH_BOX_INL +#define NV_MATH_BOX_INL + +#include "Box.h" +#include "Vector.inl" + +#include // FLT_MAX + +namespace nv +{ + // Default ctor. + Box::Box() { }; + + // Copy ctor. + Box::Box(const Box & b) : minCorner(b.minCorner), maxCorner(b.maxCorner) { } + + // Init ctor. + Box::Box(const Vector3 & mins, const Vector3 & maxs) : minCorner(mins), maxCorner(maxs) { } + + // Assignment operator. + Box & Box::operator=(const Box & b) { minCorner = b.minCorner; maxCorner = b.maxCorner; return *this; } + + // Clear the bounds. + void Box::clearBounds() + { + minCorner.set(FLT_MAX, FLT_MAX, FLT_MAX); + maxCorner.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); + } + + // Build a cube centered on center and with edge = 2*dist + void Box::cube(const Vector3 & center, float dist) + { + setCenterExtents(center, Vector3(dist, dist, dist)); + } + + // Build a box, given center and extents. + void Box::setCenterExtents(const Vector3 & center, const Vector3 & extents) + { + minCorner = center - extents; + maxCorner = center + extents; + } + + // Get box center. + Vector3 Box::center() const + { + return (minCorner + maxCorner) * 0.5f; + } + + // Return extents of the box. + Vector3 Box::extents() const + { + return (maxCorner - minCorner) * 0.5f; + } + + // Return extents of the box. + scalar Box::extents(uint axis) const + { + nvDebugCheck(axis < 3); + if (axis == 0) return (maxCorner.x - minCorner.x) * 0.5f; + if (axis == 1) return (maxCorner.y - minCorner.y) * 0.5f; + if (axis == 2) return (maxCorner.z - minCorner.z) * 0.5f; + nvAssume(false); + return 0.0f; + } + + // Add a point to this box. + void Box::addPointToBounds(const Vector3 & p) + { + minCorner = min(minCorner, p); + maxCorner = max(maxCorner, p); + } + + // Add a box to this box. + void Box::addBoxToBounds(const Box & b) + { + minCorner = min(minCorner, b.minCorner); + maxCorner = max(maxCorner, b.maxCorner); + } + + // Translate box. + void Box::translate(const Vector3 & v) + { + minCorner += v; + maxCorner += v; + } + + // Scale the box. + void Box::scale(float s) + { + minCorner *= s; + maxCorner *= s; + } + + // Expand the box by a fixed amount. + void Box::expand(float r) { + minCorner -= Vector3(r,r,r); + maxCorner += Vector3(r,r,r); + } + + // Get the area of the box. + float Box::area() const + { + const Vector3 d = extents(); + return 8.0f * (d.x*d.y + d.x*d.z + d.y*d.z); + } + + // Get the volume of the box. + float Box::volume() const + { + Vector3 d = extents(); + return 8.0f * (d.x * d.y * d.z); + } + + // Return true if the box contains the given point. + bool Box::contains(const Vector3 & p) const + { + return + minCorner.x < p.x && minCorner.y < p.y && minCorner.z < p.z && + maxCorner.x > p.x && maxCorner.y > p.y && maxCorner.z > p.z; + } + + // Split the given box in 8 octants and assign the ith one to this box. + void Box::setOctant(const Box & box, const Vector3 & center, int i) + { + minCorner = box.minCorner; + maxCorner = box.maxCorner; + + if (i & 4) minCorner.x = center.x; + else maxCorner.x = center.x; + if (i & 2) minCorner.y = center.y; + else maxCorner.y = center.y; + if (i & 1) minCorner.z = center.z; + else maxCorner.z = center.z; + } + +} // nv namespace + + +#endif // NV_MATH_BOX_INL diff --git a/src/nvmath/Color.cpp b/src/nvmath/Color.cpp new file mode 100644 index 0000000..befaa99 --- /dev/null +++ b/src/nvmath/Color.cpp @@ -0,0 +1,4 @@ +// This code is in the public domain -- castanyo@yahoo.es + +#include "Color.h" +#include "Color.inl" diff --git a/src/nvmath/Color.h b/src/nvmath/Color.h index 0f27782..7324723 100644 --- a/src/nvmath/Color.h +++ b/src/nvmath/Color.h @@ -4,8 +4,7 @@ #ifndef NV_MATH_COLOR_H #define NV_MATH_COLOR_H -#include "nvcore/Debug.h" -#include "nvmath/Vector.h" +#include "nvmath.h" namespace nv { @@ -119,83 +118,6 @@ namespace nv }; }; - - /// Clamp color components. - inline Vector3 colorClamp(Vector3::Arg c) - { - return Vector3(clamp(c.x, 0.0f, 1.0f), clamp(c.y, 0.0f, 1.0f), clamp(c.z, 0.0f, 1.0f)); - } - - /// Clamp without allowing the hue to change. - inline Vector3 colorNormalize(Vector3::Arg c) - { - float scale = 1.0f; - if (c.x > scale) scale = c.x; - if (c.y > scale) scale = c.y; - if (c.z > scale) scale = c.z; - return c / scale; - } - - /// Convert Color32 to Color16. - inline Color16 toColor16(Color32 c) - { - Color16 color; - // rrrrrggggggbbbbb - // rrrrr000gggggg00bbbbb000 - // color.u = (c.u >> 3) & 0x1F; - // color.u |= (c.u >> 5) & 0x7E0; - // color.u |= (c.u >> 8) & 0xF800; - - color.r = c.r >> 3; - color.g = c.g >> 2; - color.b = c.b >> 3; - return color; - } - - - /// Promote 16 bit color to 32 bit using regular bit expansion. - inline Color32 toColor32(Color16 c) - { - Color32 color; - // c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); - // c.u |= (c.u >> 5) & 0x070007; - // c.u |= (c.u >> 6) & 0x000300; - - color.b = (c.b << 3) | (c.b >> 2); - color.g = (c.g << 2) | (c.g >> 4); - color.r = (c.r << 3) | (c.r >> 2); - color.a = 0xFF; - - return color; - } - - inline Color32 toColor32(Vector4::Arg v) - { - Color32 color; - color.r = uint8(clamp(v.x, 0.0f, 1.0f) * 255); - color.g = uint8(clamp(v.y, 0.0f, 1.0f) * 255); - color.b = uint8(clamp(v.z, 0.0f, 1.0f) * 255); - color.a = uint8(clamp(v.w, 0.0f, 1.0f) * 255); - - return color; - } - - inline Vector4 toVector4(Color32 c) - { - const float scale = 1.0f / 255.0f; - return Vector4(c.r * scale, c.g * scale, c.b * scale, c.a * scale); - } - - - inline float perceptualColorDistance(Vector3::Arg c0, Vector3::Arg c1) - { - float rmean = (c0.x + c1.x) * 0.5f; - float r = c1.x - c0.x; - float g = c1.y - c0.y; - float b = c1.z - c0.z; - return sqrtf((2 + rmean)*r*r + 4*g*g + (3 - rmean)*b*b); - } - } // nv namespace #endif // NV_MATH_COLOR_H diff --git a/src/nvmath/Color.inl b/src/nvmath/Color.inl new file mode 100644 index 0000000..6da2f3a --- /dev/null +++ b/src/nvmath/Color.inl @@ -0,0 +1,92 @@ +// This code is in the public domain -- castanyo@yahoo.es + +#pragma once +#ifndef NV_MATH_COLOR_INL +#define NV_MATH_COLOR_INL + +#include "Color.h" +#include "Vector.inl" + + +namespace nv +{ + + /// Clamp color components. + inline Vector3 colorClamp(Vector3::Arg c) + { + return Vector3(clamp(c.x, 0.0f, 1.0f), clamp(c.y, 0.0f, 1.0f), clamp(c.z, 0.0f, 1.0f)); + } + + /// Clamp without allowing the hue to change. + inline Vector3 colorNormalize(Vector3::Arg c) + { + float scale = 1.0f; + if (c.x > scale) scale = c.x; + if (c.y > scale) scale = c.y; + if (c.z > scale) scale = c.z; + return c / scale; + } + + /// Convert Color32 to Color16. + inline Color16 toColor16(Color32 c) + { + Color16 color; + // rrrrrggggggbbbbb + // rrrrr000gggggg00bbbbb000 + // color.u = (c.u >> 3) & 0x1F; + // color.u |= (c.u >> 5) & 0x7E0; + // color.u |= (c.u >> 8) & 0xF800; + + color.r = c.r >> 3; + color.g = c.g >> 2; + color.b = c.b >> 3; + return color; + } + + + /// Promote 16 bit color to 32 bit using regular bit expansion. + inline Color32 toColor32(Color16 c) + { + Color32 color; + // c.u = ((col0.u << 3) & 0xf8) | ((col0.u << 5) & 0xfc00) | ((col0.u << 8) & 0xf80000); + // c.u |= (c.u >> 5) & 0x070007; + // c.u |= (c.u >> 6) & 0x000300; + + color.b = (c.b << 3) | (c.b >> 2); + color.g = (c.g << 2) | (c.g >> 4); + color.r = (c.r << 3) | (c.r >> 2); + color.a = 0xFF; + + return color; + } + + inline Color32 toColor32(Vector4::Arg v) + { + Color32 color; + color.r = uint8(clamp(v.x, 0.0f, 1.0f) * 255); + color.g = uint8(clamp(v.y, 0.0f, 1.0f) * 255); + color.b = uint8(clamp(v.z, 0.0f, 1.0f) * 255); + color.a = uint8(clamp(v.w, 0.0f, 1.0f) * 255); + + return color; + } + + inline Vector4 toVector4(Color32 c) + { + const float scale = 1.0f / 255.0f; + return Vector4(c.r * scale, c.g * scale, c.b * scale, c.a * scale); + } + + + inline float perceptualColorDistance(Vector3::Arg c0, Vector3::Arg c1) + { + float rmean = (c0.x + c1.x) * 0.5f; + float r = c1.x - c0.x; + float g = c1.y - c0.y; + float b = c1.z - c0.z; + return sqrtf((2 + rmean)*r*r + 4*g*g + (3 - rmean)*b*b); + } + +} // nv namespace + +#endif // NV_MATH_COLOR_INL diff --git a/src/nvmath/Fitting.cpp b/src/nvmath/Fitting.cpp index ba0e5e5..98172b4 100644 --- a/src/nvmath/Fitting.cpp +++ b/src/nvmath/Fitting.cpp @@ -1,6 +1,9 @@ // This code is in the public domain -- Ignacio Castaño #include "Fitting.h" +#include "Vector.inl" +#include "Plane.inl" + #include "nvcore/Utils.h" // max, swap #include // FLT_MAX diff --git a/src/nvmath/Fitting.h b/src/nvmath/Fitting.h index 6085ea9..84d397f 100644 --- a/src/nvmath/Fitting.h +++ b/src/nvmath/Fitting.h @@ -4,27 +4,28 @@ #ifndef NV_MATH_FITTING_H #define NV_MATH_FITTING_H -#include "nvmath/nvmath.h" -#include "nvmath/Vector.h" -#include "nvmath/Plane.h" +#include "nvmath.h" namespace nv { + class Vector3; + class Plane; + namespace Fit { Vector3 computeCentroid(int n, const Vector3 * points); - Vector3 computeCentroid(int n, const Vector3 * points, const float * weights, Vector3::Arg metric); + Vector3 computeCentroid(int n, const Vector3 * points, const float * weights, const Vector3 & metric); Vector3 computeCovariance(int n, const Vector3 * points, float * covariance); - Vector3 computeCovariance(int n, const Vector3 * points, const float * weights, Vector3::Arg metric, float * covariance); + Vector3 computeCovariance(int n, const Vector3 * points, const float * weights, const Vector3 & metric, float * covariance); Vector3 computePrincipalComponent(int n, const Vector3 * points); - Vector3 computePrincipalComponent(int n, const Vector3 * points, const float * weights, Vector3::Arg metric); + Vector3 computePrincipalComponent(int n, const Vector3 * points, const float * weights, const Vector3 & metric); Plane bestPlane(int n, const Vector3 * points); // Returns number of clusters [1-4]. - int compute4Means(int n, const Vector3 * points, const float * weights, Vector3::Arg metric, Vector3 * cluster); + int compute4Means(int n, const Vector3 * points, const float * weights, const Vector3 & metric, Vector3 * cluster); } } // nv namespace diff --git a/src/nvmath/Plane.cpp b/src/nvmath/Plane.cpp index 6c82d14..e292ee0 100644 --- a/src/nvmath/Plane.cpp +++ b/src/nvmath/Plane.cpp @@ -1,6 +1,7 @@ // This code is in the public domain -- castanyo@yahoo.es #include "Plane.h" +#include "Plane.inl" #include "Matrix.h" namespace nv diff --git a/src/nvmath/Plane.h b/src/nvmath/Plane.h index 90c4a54..0552801 100644 --- a/src/nvmath/Plane.h +++ b/src/nvmath/Plane.h @@ -11,7 +11,6 @@ namespace nv { class Matrix; - class NVMATH_CLASS Plane { public: @@ -37,40 +36,6 @@ namespace nv Vector4 p; }; - inline Plane::Plane() {} - inline Plane::Plane(float x, float y, float z, float w) : p(x, y, z, w) {} - inline Plane::Plane(Vector4::Arg v) : p(v) {} - inline Plane::Plane(Vector3::Arg v, float d) : p(v, d) {} - inline Plane::Plane(Vector3::Arg normal, Vector3::Arg point) : p(normal, dot(normal, point)) {} - - inline const Plane & Plane::operator=(Plane::Arg v) { p = v.p; return *this; } - - inline Vector3 Plane::vector() const { return p.xyz(); } - inline scalar Plane::offset() const { return p.w; } - - inline const Vector4 & Plane::asVector() const { return p; } - inline Vector4 & Plane::asVector() { return p; } - - // Normalize plane. - inline Plane normalize(Plane::Arg plane, float epsilon = NV_EPSILON) - { - const float len = length(plane.vector()); - nvDebugCheck(!isZero(len, epsilon)); - const float inv = 1.0f / len; - return Plane(plane.asVector() * inv); - } - - // Get the signed distance from the given point to this plane. - inline float distance(Plane::Arg plane, Vector3::Arg point) - { - return dot(plane.vector(), point) - plane.offset(); - } - - inline void Plane::operator*=(scalar s) - { - scale(p, s); - } - Plane transformPlane(const Matrix&, Plane::Arg); Vector3 planeIntersection(Plane::Arg a, Plane::Arg b, Plane::Arg c); diff --git a/src/nvmath/Plane.inl b/src/nvmath/Plane.inl new file mode 100644 index 0000000..c8bd3ea --- /dev/null +++ b/src/nvmath/Plane.inl @@ -0,0 +1,48 @@ +// This code is in the public domain -- Ignacio Castaño + +#pragma once +#ifndef NV_MATH_PLANE_INL +#define NV_MATH_PLANE_INL + +#include "Plane.h" +#include "Vector.inl" + +namespace nv +{ + inline Plane::Plane() {} + inline Plane::Plane(float x, float y, float z, float w) : p(x, y, z, w) {} + inline Plane::Plane(Vector4::Arg v) : p(v) {} + inline Plane::Plane(Vector3::Arg v, float d) : p(v, d) {} + inline Plane::Plane(Vector3::Arg normal, Vector3::Arg point) : p(normal, dot(normal, point)) {} + + inline const Plane & Plane::operator=(Plane::Arg v) { p = v.p; return *this; } + + inline Vector3 Plane::vector() const { return p.xyz(); } + inline scalar Plane::offset() const { return p.w; } + + inline const Vector4 & Plane::asVector() const { return p; } + inline Vector4 & Plane::asVector() { return p; } + + // Normalize plane. + inline Plane normalize(Plane::Arg plane, float epsilon = NV_EPSILON) + { + const float len = length(plane.vector()); + nvDebugCheck(!isZero(len, epsilon)); + const float inv = 1.0f / len; + return Plane(plane.asVector() * inv); + } + + // Get the signed distance from the given point to this plane. + inline float distance(Plane::Arg plane, Vector3::Arg point) + { + return dot(plane.vector(), point) - plane.offset(); + } + + inline void Plane::operator*=(scalar s) + { + scale(p, s); + } + +} // nv namespace + +#endif // NV_MATH_PLANE_H diff --git a/src/nvmath/Vector.cpp b/src/nvmath/Vector.cpp new file mode 100644 index 0000000..9122a1b --- /dev/null +++ b/src/nvmath/Vector.cpp @@ -0,0 +1,4 @@ +// This code is in the public domain -- castanyo@yahoo.es + +#include "Vector.h" +#include "Vector.inl" diff --git a/src/nvmath/Vector.h b/src/nvmath/Vector.h index c94e306..a54ccce 100644 --- a/src/nvmath/Vector.h +++ b/src/nvmath/Vector.h @@ -5,7 +5,6 @@ #define NV_MATH_VECTOR_H #include "nvmath.h" -#include "nvcore/Utils.h" // min, max namespace nv { @@ -136,702 +135,6 @@ namespace nv template T to(Vector4::Arg v) { return T(v.x, v.y, v.z, v.w); } - - // Vector2 - - inline Vector2::Vector2() {} - inline Vector2::Vector2(scalar f) : x(f), y(f) {} - inline Vector2::Vector2(scalar x, scalar y) : x(x), y(y) {} - inline Vector2::Vector2(Vector2::Arg v) : x(v.x), y(v.y) {} - - inline const Vector2 & Vector2::operator=(Vector2::Arg v) - { - x = v.x; - y = v.y; - return *this; - } - - inline const scalar * Vector2::ptr() const - { - return &x; - } - - inline void Vector2::set(scalar x, scalar y) - { - this->x = x; - this->y = y; - } - - inline Vector2 Vector2::operator-() const - { - return Vector2(-x, -y); - } - - inline void Vector2::operator+=(Vector2::Arg v) - { - x += v.x; - y += v.y; - } - - inline void Vector2::operator-=(Vector2::Arg v) - { - x -= v.x; - y -= v.y; - } - - inline void Vector2::operator*=(scalar s) - { - x *= s; - y *= s; - } - - inline void Vector2::operator*=(Vector2::Arg v) - { - x *= v.x; - y *= v.y; - } - - inline bool operator==(Vector2::Arg a, Vector2::Arg b) - { - return a.x == b.x && a.y == b.y; - } - inline bool operator!=(Vector2::Arg a, Vector2::Arg b) - { - return a.x != b.x || a.y != b.y; - } - - - // Vector3 - - inline Vector3::Vector3() {} - inline Vector3::Vector3(scalar f) : x(f), y(f), z(f) {} - inline Vector3::Vector3(scalar x, scalar y, scalar z) : x(x), y(y), z(z) {} - inline Vector3::Vector3(Vector2::Arg v, scalar z) : x(v.x), y(v.y), z(z) {} - inline Vector3::Vector3(Vector3::Arg v) : x(v.x), y(v.y), z(v.z) {} - - inline const Vector3 & Vector3::operator=(Vector3::Arg v) - { - x = v.x; - y = v.y; - z = v.z; - return *this; - } - - - inline Vector2 Vector3::xy() const - { - return Vector2(x, y); - } - - inline const scalar * Vector3::ptr() const - { - return &x; - } - - inline void Vector3::set(scalar x, scalar y, scalar z) - { - this->x = x; - this->y = y; - this->z = z; - } - - inline Vector3 Vector3::operator-() const - { - return Vector3(-x, -y, -z); - } - - inline void Vector3::operator+=(Vector3::Arg v) - { - x += v.x; - y += v.y; - z += v.z; - } - - inline void Vector3::operator-=(Vector3::Arg v) - { - x -= v.x; - y -= v.y; - z -= v.z; - } - - inline void Vector3::operator*=(scalar s) - { - x *= s; - y *= s; - z *= s; - } - - inline void Vector3::operator/=(scalar s) - { - float is = 1.0f / s; - x *= is; - y *= is; - z *= is; - } - - inline void Vector3::operator*=(Vector3::Arg v) - { - x *= v.x; - y *= v.y; - z *= v.z; - } - - inline bool operator==(Vector3::Arg a, Vector3::Arg b) - { - return a.x == b.x && a.y == b.y && a.z == b.z; - } - inline bool operator!=(Vector3::Arg a, Vector3::Arg b) - { - return a.x != b.x || a.y != b.y || a.z != b.z; - } - - - // Vector4 - - inline Vector4::Vector4() {} - inline Vector4::Vector4(scalar f) : x(f), y(f), z(f), w(f) {} - inline Vector4::Vector4(scalar x, scalar y, scalar z, scalar w) : x(x), y(y), z(z), w(w) {} - inline Vector4::Vector4(Vector2::Arg v, scalar z, scalar w) : x(v.x), y(v.y), z(z), w(w) {} - inline Vector4::Vector4(Vector2::Arg v, Vector2::Arg u) : x(v.x), y(v.y), z(u.x), w(u.y) {} - inline Vector4::Vector4(Vector3::Arg v, scalar w) : x(v.x), y(v.y), z(v.z), w(w) {} - inline Vector4::Vector4(Vector4::Arg v) : x(v.x), y(v.y), z(v.z), w(v.w) {} - - inline const Vector4 & Vector4::operator=(const Vector4 & v) - { - x = v.x; - y = v.y; - z = v.z; - w = v.w; - return *this; - } - - inline Vector2 Vector4::xy() const - { - return Vector2(x, y); - } - - inline Vector2 Vector4::zw() const - { - return Vector2(z, w); - } - - inline Vector3 Vector4::xyz() const - { - return Vector3(x, y, z); - } - - inline const scalar * Vector4::ptr() const - { - return &x; - } - - inline void Vector4::set(scalar x, scalar y, scalar z, scalar w) - { - this->x = x; - this->y = y; - this->z = z; - this->w = w; - } - - inline Vector4 Vector4::operator-() const - { - return Vector4(-x, -y, -z, -w); - } - - inline void Vector4::operator+=(Vector4::Arg v) - { - x += v.x; - y += v.y; - z += v.z; - w += v.w; - } - - inline void Vector4::operator-=(Vector4::Arg v) - { - x -= v.x; - y -= v.y; - z -= v.z; - w -= v.w; - } - - inline void Vector4::operator*=(scalar s) - { - x *= s; - y *= s; - z *= s; - w *= s; - } - - inline void Vector4::operator*=(Vector4::Arg v) - { - x *= v.x; - y *= v.y; - z *= v.z; - w *= v.w; - } - - inline bool operator==(Vector4::Arg a, Vector4::Arg b) - { - return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; - } - inline bool operator!=(Vector4::Arg a, Vector4::Arg b) - { - return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w; - } - - - - // Functions - - - // Vector2 - - inline Vector2 add(Vector2::Arg a, Vector2::Arg b) - { - return Vector2(a.x + b.x, a.y + b.y); - } - inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b) - { - return add(a, b); - } - - inline Vector2 sub(Vector2::Arg a, Vector2::Arg b) - { - return Vector2(a.x - b.x, a.y - b.y); - } - inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b) - { - return sub(a, b); - } - - inline Vector2 scale(Vector2::Arg v, scalar s) - { - return Vector2(v.x * s, v.y * s); - } - - inline Vector2 scale(Vector2::Arg v, Vector2::Arg s) - { - return Vector2(v.x * s.x, v.y * s.y); - } - - inline Vector2 operator*(Vector2::Arg v, scalar s) - { - return scale(v, s); - } - - inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2) - { - return Vector2(v1.x*v2.x, v1.y*v2.y); - } - - inline Vector2 operator*(scalar s, Vector2::Arg v) - { - return scale(v, s); - } - - inline Vector2 operator/(Vector2::Arg v, scalar s) - { - return scale(v, 1.0f/s); - } - - inline scalar dot(Vector2::Arg a, Vector2::Arg b) - { - return a.x * b.x + a.y * b.y; - } - - inline scalar lengthSquared(Vector2::Arg v) - { - return v.x * v.x + v.y * v.y; - } - - inline scalar length(Vector2::Arg v) - { - return sqrtf(lengthSquared(v)); - } - - inline scalar inverseLength(Vector2::Arg v) - { - return 1.0f / sqrtf(lengthSquared(v)); - } - - inline bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON) - { - return equal(length(v), 1, epsilon); - } - - inline Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON) - { - float l = length(v); - nvDebugCheck(!isZero(l, epsilon)); - Vector2 n = scale(v, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; - } - - inline Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON) - { - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return scale(v, 1.0f / l); - } - - // Safe, branchless normalization from Andy Firth. All error checking ommitted. - // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ - inline Vector2 normalizeFast(Vector2::Arg v) - { - const float very_small_float = 1.0e-037f; - float l = very_small_float + length(v); - return scale(v, 1.0f / l); - } - - inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON) - { - return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); - } - - inline Vector2 min(Vector2::Arg a, Vector2::Arg b) - { - return Vector2(min(a.x, b.x), min(a.y, b.y)); - } - - inline Vector2 max(Vector2::Arg a, Vector2::Arg b) - { - return Vector2(max(a.x, b.x), max(a.y, b.y)); - } - - inline bool isValid(Vector2::Arg v) - { - return isFinite(v.x) && isFinite(v.y); - } - - inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f)) - { - if (!isValid(v)) return fallback; - Vector2 vf = v; - nv::floatCleanup(vf.component, 2); - return vf; - } - - inline float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) - { - Vector2 v0 = a - c; - Vector2 v1 = b - c; - - return (v0.x * v1.y - v0.y * v1.x); - } - - - // Vector3 - - inline Vector3 add(Vector3::Arg a, Vector3::Arg b) - { - return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); - } - inline Vector3 add(Vector3::Arg a, float b) - { - return Vector3(a.x + b, a.y + b, a.z + b); - } - inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b) - { - return add(a, b); - } - inline Vector3 operator+(Vector3::Arg a, float b) - { - return add(a, b); - } - - inline Vector3 sub(Vector3::Arg a, Vector3::Arg b) - { - return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); - } - inline Vector3 sub(Vector3::Arg a, float b) - { - return Vector3(a.x - b, a.y - b, a.z - b); - } - inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b) - { - return sub(a, b); - } - inline Vector3 operator-(Vector3::Arg a, float b) - { - return sub(a, b); - } - - inline Vector3 cross(Vector3::Arg a, Vector3::Arg b) - { - return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); - } - - inline Vector3 scale(Vector3::Arg v, scalar s) - { - return Vector3(v.x * s, v.y * s, v.z * s); - } - - inline Vector3 scale(Vector3::Arg v, Vector3::Arg s) - { - return Vector3(v.x * s.x, v.y * s.y, v.z * s.z); - } - - inline Vector3 operator*(Vector3::Arg v, scalar s) - { - return scale(v, s); - } - - inline Vector3 operator*(scalar s, Vector3::Arg v) - { - return scale(v, s); - } - - inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s) - { - return scale(v, s); - } - - inline Vector3 operator/(Vector3::Arg v, scalar s) - { - return scale(v, 1.0f/s); - } - - /*inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, scalar s) - { - return Vector3(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s); - }*/ - - inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, scalar t) - { - const scalar s = 1.0f - t; - return Vector3(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z); - } - - inline scalar dot(Vector3::Arg a, Vector3::Arg b) - { - return a.x * b.x + a.y * b.y + a.z * b.z; - } - - inline scalar lengthSquared(Vector3::Arg v) - { - return v.x * v.x + v.y * v.y + v.z * v.z; - } - - inline scalar length(Vector3::Arg v) - { - return sqrtf(lengthSquared(v)); - } - - inline scalar inverseLength(Vector3::Arg v) - { - return 1.0f / sqrtf(lengthSquared(v)); - } - - inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON) - { - return equal(length(v), 1, epsilon); - } - - inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON) - { - float l = length(v); - nvDebugCheck(!isZero(l, epsilon)); - Vector3 n = scale(v, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; - } - - inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON) - { - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return scale(v, 1.0f / l); - } - - // Safe, branchless normalization from Andy Firth. All error checking ommitted. - // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ - inline Vector3 normalizeFast(Vector3::Arg v) - { - const float very_small_float = 1.0e-037f; - float l = very_small_float + length(v); - return scale(v, 1.0f / l); - } - - inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON) - { - return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon); - } - - inline Vector3 min(Vector3::Arg a, Vector3::Arg b) - { - return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); - } - - inline Vector3 max(Vector3::Arg a, Vector3::Arg b) - { - return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); - } - - inline Vector3 clamp(Vector3::Arg v, float min, float max) - { - return Vector3(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max)); - } - - inline Vector3 floor(Vector3::Arg v) - { - return Vector3(floorf(v.x), floorf(v.y), floorf(v.z)); - } - - inline Vector3 ceil(Vector3::Arg v) - { - return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z)); - } - - inline bool isValid(Vector3::Arg v) - { - return isFinite(v.x) && isFinite(v.y) && isFinite(v.z); - } - - inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f)) - { - if (!isValid(v)) return fallback; - Vector3 vf = v; - nv::floatCleanup(vf.component, 3); - return vf; - } - - - - // Vector4 - - inline Vector4 add(Vector4::Arg a, Vector4::Arg b) - { - return Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); - } - inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b) - { - return add(a, b); - } - - inline Vector4 sub(Vector4::Arg a, Vector4::Arg b) - { - return Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); - } - inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b) - { - return sub(a, b); - } - - inline Vector4 scale(Vector4::Arg v, scalar s) - { - return Vector4(v.x * s, v.y * s, v.z * s, v.w * s); - } - - inline Vector4 scale(Vector4::Arg v, Vector4::Arg s) - { - return Vector4(v.x * s.x, v.y * s.y, v.z * s.z, v.w * s.w); - } - - inline Vector4 operator*(Vector4::Arg v, scalar s) - { - return scale(v, s); - } - - inline Vector4 operator*(scalar s, Vector4::Arg v) - { - return scale(v, s); - } - - inline Vector4 operator/(Vector4::Arg v, scalar s) - { - return scale(v, 1.0f/s); - } - - inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, scalar s) - { - return Vector4(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s, a.w + b.w * s); - } - - inline scalar dot(Vector4::Arg a, Vector4::Arg b) - { - return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; - } - - inline scalar lengthSquared(Vector4::Arg v) - { - return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; - } - - inline scalar length(Vector4::Arg v) - { - return sqrtf(lengthSquared(v)); - } - - inline scalar inverseLength(Vector4::Arg v) - { - return 1.0f / sqrtf(lengthSquared(v)); - } - - inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON) - { - return equal(length(v), 1, epsilon); - } - - inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON) - { - float l = length(v); - nvDebugCheck(!isZero(l, epsilon)); - Vector4 n = scale(v, 1.0f / l); - nvDebugCheck(isNormalized(n)); - return n; - } - - inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON) - { - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return scale(v, 1.0f / l); - } - - // Safe, branchless normalization from Andy Firth. All error checking ommitted. - // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ - inline Vector4 normalizeFast(Vector4::Arg v) - { - const float very_small_float = 1.0e-037f; - float l = very_small_float + length(v); - return scale(v, 1.0f / l); - } - - inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON) - { - return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon) && equal(v1.w, v2.w, epsilon); - } - - inline Vector4 min(Vector4::Arg a, Vector4::Arg b) - { - return Vector4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w)); - } - - inline Vector4 max(Vector4::Arg a, Vector4::Arg b) - { - return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); - } - - inline bool isValid(Vector4::Arg v) - { - return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w); - } - - inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f)) - { - if (!isValid(v)) return fallback; - Vector4 vf = v; - nv::floatCleanup(vf.component, 4); - return vf; - } - } // nv namespace #endif // NV_MATH_VECTOR_H diff --git a/src/nvmath/Vector.inl b/src/nvmath/Vector.inl new file mode 100644 index 0000000..a676ee4 --- /dev/null +++ b/src/nvmath/Vector.inl @@ -0,0 +1,717 @@ +// This code is in the public domain -- castanyo@yahoo.es + +#pragma once +#ifndef NV_MATH_VECTOR_INL +#define NV_MATH_VECTOR_INL + +#include "Vector.h" +#include "nvcore/Utils.h" // min, max + +namespace nv +{ + + // Helpers to convert vector types. Assume T has x,y members and 2 argument constructor. + //template T to(Vector2::Arg v) { return T(v.x, v.y); } + + // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor. + //template T to(Vector3::Arg v) { return T(v.x, v.y, v.z); } + + // Helpers to convert vector types. Assume T has x,y,z members and 3 argument constructor. + //template T to(Vector4::Arg v) { return T(v.x, v.y, v.z, v.w); } + + + // Vector2 + inline Vector2::Vector2() {} + inline Vector2::Vector2(scalar f) : x(f), y(f) {} + inline Vector2::Vector2(scalar x, scalar y) : x(x), y(y) {} + inline Vector2::Vector2(Vector2::Arg v) : x(v.x), y(v.y) {} + + inline const Vector2 & Vector2::operator=(Vector2::Arg v) + { + x = v.x; + y = v.y; + return *this; + } + + inline const scalar * Vector2::ptr() const + { + return &x; + } + + inline void Vector2::set(scalar x, scalar y) + { + this->x = x; + this->y = y; + } + + inline Vector2 Vector2::operator-() const + { + return Vector2(-x, -y); + } + + inline void Vector2::operator+=(Vector2::Arg v) + { + x += v.x; + y += v.y; + } + + inline void Vector2::operator-=(Vector2::Arg v) + { + x -= v.x; + y -= v.y; + } + + inline void Vector2::operator*=(scalar s) + { + x *= s; + y *= s; + } + + inline void Vector2::operator*=(Vector2::Arg v) + { + x *= v.x; + y *= v.y; + } + + inline bool operator==(Vector2::Arg a, Vector2::Arg b) + { + return a.x == b.x && a.y == b.y; + } + inline bool operator!=(Vector2::Arg a, Vector2::Arg b) + { + return a.x != b.x || a.y != b.y; + } + + + // Vector3 + inline Vector3::Vector3() {} + inline Vector3::Vector3(scalar f) : x(f), y(f), z(f) {} + inline Vector3::Vector3(scalar x, scalar y, scalar z) : x(x), y(y), z(z) {} + inline Vector3::Vector3(Vector2::Arg v, scalar z) : x(v.x), y(v.y), z(z) {} + inline Vector3::Vector3(Vector3::Arg v) : x(v.x), y(v.y), z(v.z) {} + + inline const Vector3 & Vector3::operator=(Vector3::Arg v) + { + x = v.x; + y = v.y; + z = v.z; + return *this; + } + + + inline Vector2 Vector3::xy() const + { + return Vector2(x, y); + } + + inline const scalar * Vector3::ptr() const + { + return &x; + } + + inline void Vector3::set(scalar x, scalar y, scalar z) + { + this->x = x; + this->y = y; + this->z = z; + } + + inline Vector3 Vector3::operator-() const + { + return Vector3(-x, -y, -z); + } + + inline void Vector3::operator+=(Vector3::Arg v) + { + x += v.x; + y += v.y; + z += v.z; + } + + inline void Vector3::operator-=(Vector3::Arg v) + { + x -= v.x; + y -= v.y; + z -= v.z; + } + + inline void Vector3::operator*=(scalar s) + { + x *= s; + y *= s; + z *= s; + } + + inline void Vector3::operator/=(scalar s) + { + float is = 1.0f / s; + x *= is; + y *= is; + z *= is; + } + + inline void Vector3::operator*=(Vector3::Arg v) + { + x *= v.x; + y *= v.y; + z *= v.z; + } + + inline bool operator==(Vector3::Arg a, Vector3::Arg b) + { + return a.x == b.x && a.y == b.y && a.z == b.z; + } + inline bool operator!=(Vector3::Arg a, Vector3::Arg b) + { + return a.x != b.x || a.y != b.y || a.z != b.z; + } + + + // Vector4 + inline Vector4::Vector4() {} + inline Vector4::Vector4(scalar f) : x(f), y(f), z(f), w(f) {} + inline Vector4::Vector4(scalar x, scalar y, scalar z, scalar w) : x(x), y(y), z(z), w(w) {} + inline Vector4::Vector4(Vector2::Arg v, scalar z, scalar w) : x(v.x), y(v.y), z(z), w(w) {} + inline Vector4::Vector4(Vector2::Arg v, Vector2::Arg u) : x(v.x), y(v.y), z(u.x), w(u.y) {} + inline Vector4::Vector4(Vector3::Arg v, scalar w) : x(v.x), y(v.y), z(v.z), w(w) {} + inline Vector4::Vector4(Vector4::Arg v) : x(v.x), y(v.y), z(v.z), w(v.w) {} + + inline const Vector4 & Vector4::operator=(const Vector4 & v) + { + x = v.x; + y = v.y; + z = v.z; + w = v.w; + return *this; + } + + inline Vector2 Vector4::xy() const + { + return Vector2(x, y); + } + + inline Vector2 Vector4::zw() const + { + return Vector2(z, w); + } + + inline Vector3 Vector4::xyz() const + { + return Vector3(x, y, z); + } + + inline const scalar * Vector4::ptr() const + { + return &x; + } + + inline void Vector4::set(scalar x, scalar y, scalar z, scalar w) + { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } + + inline Vector4 Vector4::operator-() const + { + return Vector4(-x, -y, -z, -w); + } + + inline void Vector4::operator+=(Vector4::Arg v) + { + x += v.x; + y += v.y; + z += v.z; + w += v.w; + } + + inline void Vector4::operator-=(Vector4::Arg v) + { + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; + } + + inline void Vector4::operator*=(scalar s) + { + x *= s; + y *= s; + z *= s; + w *= s; + } + + inline void Vector4::operator*=(Vector4::Arg v) + { + x *= v.x; + y *= v.y; + z *= v.z; + w *= v.w; + } + + inline bool operator==(Vector4::Arg a, Vector4::Arg b) + { + return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; + } + inline bool operator!=(Vector4::Arg a, Vector4::Arg b) + { + return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w; + } + + + + // Functions + + + // Vector2 + + inline Vector2 add(Vector2::Arg a, Vector2::Arg b) + { + return Vector2(a.x + b.x, a.y + b.y); + } + inline Vector2 operator+(Vector2::Arg a, Vector2::Arg b) + { + return add(a, b); + } + + inline Vector2 sub(Vector2::Arg a, Vector2::Arg b) + { + return Vector2(a.x - b.x, a.y - b.y); + } + inline Vector2 operator-(Vector2::Arg a, Vector2::Arg b) + { + return sub(a, b); + } + + inline Vector2 scale(Vector2::Arg v, scalar s) + { + return Vector2(v.x * s, v.y * s); + } + + inline Vector2 scale(Vector2::Arg v, Vector2::Arg s) + { + return Vector2(v.x * s.x, v.y * s.y); + } + + inline Vector2 operator*(Vector2::Arg v, scalar s) + { + return scale(v, s); + } + + inline Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2) + { + return Vector2(v1.x*v2.x, v1.y*v2.y); + } + + inline Vector2 operator*(scalar s, Vector2::Arg v) + { + return scale(v, s); + } + + inline Vector2 operator/(Vector2::Arg v, scalar s) + { + return scale(v, 1.0f/s); + } + + inline scalar dot(Vector2::Arg a, Vector2::Arg b) + { + return a.x * b.x + a.y * b.y; + } + + inline scalar lengthSquared(Vector2::Arg v) + { + return v.x * v.x + v.y * v.y; + } + + inline scalar length(Vector2::Arg v) + { + return sqrtf(lengthSquared(v)); + } + + inline scalar inverseLength(Vector2::Arg v) + { + return 1.0f / sqrtf(lengthSquared(v)); + } + + inline bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON) + { + return equal(length(v), 1, epsilon); + } + + inline Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON) + { + float l = length(v); + nvDebugCheck(!isZero(l, epsilon)); + Vector2 n = scale(v, 1.0f / l); + nvDebugCheck(isNormalized(n)); + return n; + } + + inline Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON) + { + float l = length(v); + if (isZero(l, epsilon)) { + return fallback; + } + return scale(v, 1.0f / l); + } + + // Safe, branchless normalization from Andy Firth. All error checking ommitted. + // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ + inline Vector2 normalizeFast(Vector2::Arg v) + { + const float very_small_float = 1.0e-037f; + float l = very_small_float + length(v); + return scale(v, 1.0f / l); + } + + inline bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON) + { + return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); + } + + inline Vector2 min(Vector2::Arg a, Vector2::Arg b) + { + return Vector2(min(a.x, b.x), min(a.y, b.y)); + } + + inline Vector2 max(Vector2::Arg a, Vector2::Arg b) + { + return Vector2(max(a.x, b.x), max(a.y, b.y)); + } + + inline bool isValid(Vector2::Arg v) + { + return isFinite(v.x) && isFinite(v.y); + } + + inline Vector2 validate(Vector2::Arg v, Vector2::Arg fallback = Vector2(0.0f)) + { + if (!isValid(v)) return fallback; + Vector2 vf = v; + nv::floatCleanup(vf.component, 2); + return vf; + } + + inline float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) + { + Vector2 v0 = a - c; + Vector2 v1 = b - c; + + return (v0.x * v1.y - v0.y * v1.x); + } + + + // Vector3 + + inline Vector3 add(Vector3::Arg a, Vector3::Arg b) + { + return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); + } + inline Vector3 add(Vector3::Arg a, float b) + { + return Vector3(a.x + b, a.y + b, a.z + b); + } + inline Vector3 operator+(Vector3::Arg a, Vector3::Arg b) + { + return add(a, b); + } + inline Vector3 operator+(Vector3::Arg a, float b) + { + return add(a, b); + } + + inline Vector3 sub(Vector3::Arg a, Vector3::Arg b) + { + return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); + } + inline Vector3 sub(Vector3::Arg a, float b) + { + return Vector3(a.x - b, a.y - b, a.z - b); + } + inline Vector3 operator-(Vector3::Arg a, Vector3::Arg b) + { + return sub(a, b); + } + inline Vector3 operator-(Vector3::Arg a, float b) + { + return sub(a, b); + } + + inline Vector3 cross(Vector3::Arg a, Vector3::Arg b) + { + return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); + } + + inline Vector3 scale(Vector3::Arg v, scalar s) + { + return Vector3(v.x * s, v.y * s, v.z * s); + } + + inline Vector3 scale(Vector3::Arg v, Vector3::Arg s) + { + return Vector3(v.x * s.x, v.y * s.y, v.z * s.z); + } + + inline Vector3 operator*(Vector3::Arg v, scalar s) + { + return scale(v, s); + } + + inline Vector3 operator*(scalar s, Vector3::Arg v) + { + return scale(v, s); + } + + inline Vector3 operator*(Vector3::Arg v, Vector3::Arg s) + { + return scale(v, s); + } + + inline Vector3 operator/(Vector3::Arg v, scalar s) + { + return scale(v, 1.0f/s); + } + + /*inline Vector3 add_scaled(Vector3::Arg a, Vector3::Arg b, scalar s) + { + return Vector3(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s); + }*/ + + inline Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, scalar t) + { + const scalar s = 1.0f - t; + return Vector3(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z); + } + + inline scalar dot(Vector3::Arg a, Vector3::Arg b) + { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + inline scalar lengthSquared(Vector3::Arg v) + { + return v.x * v.x + v.y * v.y + v.z * v.z; + } + + inline scalar length(Vector3::Arg v) + { + return sqrtf(lengthSquared(v)); + } + + inline scalar inverseLength(Vector3::Arg v) + { + return 1.0f / sqrtf(lengthSquared(v)); + } + + inline bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON) + { + return equal(length(v), 1, epsilon); + } + + inline Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON) + { + float l = length(v); + nvDebugCheck(!isZero(l, epsilon)); + Vector3 n = scale(v, 1.0f / l); + nvDebugCheck(isNormalized(n)); + return n; + } + + inline Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON) + { + float l = length(v); + if (isZero(l, epsilon)) { + return fallback; + } + return scale(v, 1.0f / l); + } + + // Safe, branchless normalization from Andy Firth. All error checking ommitted. + // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ + inline Vector3 normalizeFast(Vector3::Arg v) + { + const float very_small_float = 1.0e-037f; + float l = very_small_float + length(v); + return scale(v, 1.0f / l); + } + + inline bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON) + { + return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon); + } + + inline Vector3 min(Vector3::Arg a, Vector3::Arg b) + { + return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); + } + + inline Vector3 max(Vector3::Arg a, Vector3::Arg b) + { + return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); + } + + inline Vector3 clamp(Vector3::Arg v, float min, float max) + { + return Vector3(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max)); + } + + inline Vector3 floor(Vector3::Arg v) + { + return Vector3(floorf(v.x), floorf(v.y), floorf(v.z)); + } + + inline Vector3 ceil(Vector3::Arg v) + { + return Vector3(ceilf(v.x), ceilf(v.y), ceilf(v.z)); + } + + inline bool isValid(Vector3::Arg v) + { + return isFinite(v.x) && isFinite(v.y) && isFinite(v.z); + } + + inline Vector3 validate(Vector3::Arg v, Vector3::Arg fallback = Vector3(0.0f)) + { + if (!isValid(v)) return fallback; + Vector3 vf = v; + nv::floatCleanup(vf.component, 3); + return vf; + } + + + + // Vector4 + + inline Vector4 add(Vector4::Arg a, Vector4::Arg b) + { + return Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); + } + inline Vector4 operator+(Vector4::Arg a, Vector4::Arg b) + { + return add(a, b); + } + + inline Vector4 sub(Vector4::Arg a, Vector4::Arg b) + { + return Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); + } + inline Vector4 operator-(Vector4::Arg a, Vector4::Arg b) + { + return sub(a, b); + } + + inline Vector4 scale(Vector4::Arg v, scalar s) + { + return Vector4(v.x * s, v.y * s, v.z * s, v.w * s); + } + + inline Vector4 scale(Vector4::Arg v, Vector4::Arg s) + { + return Vector4(v.x * s.x, v.y * s.y, v.z * s.z, v.w * s.w); + } + + inline Vector4 operator*(Vector4::Arg v, scalar s) + { + return scale(v, s); + } + + inline Vector4 operator*(scalar s, Vector4::Arg v) + { + return scale(v, s); + } + + inline Vector4 operator/(Vector4::Arg v, scalar s) + { + return scale(v, 1.0f/s); + } + + inline Vector4 add_scaled(Vector4::Arg a, Vector4::Arg b, scalar s) + { + return Vector4(a.x + b.x * s, a.y + b.y * s, a.z + b.z * s, a.w + b.w * s); + } + + inline scalar dot(Vector4::Arg a, Vector4::Arg b) + { + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; + } + + inline scalar lengthSquared(Vector4::Arg v) + { + return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; + } + + inline scalar length(Vector4::Arg v) + { + return sqrtf(lengthSquared(v)); + } + + inline scalar inverseLength(Vector4::Arg v) + { + return 1.0f / sqrtf(lengthSquared(v)); + } + + inline bool isNormalized(Vector4::Arg v, float epsilon = NV_NORMAL_EPSILON) + { + return equal(length(v), 1, epsilon); + } + + inline Vector4 normalize(Vector4::Arg v, float epsilon = NV_EPSILON) + { + float l = length(v); + nvDebugCheck(!isZero(l, epsilon)); + Vector4 n = scale(v, 1.0f / l); + nvDebugCheck(isNormalized(n)); + return n; + } + + inline Vector4 normalizeSafe(Vector4::Arg v, Vector4::Arg fallback, float epsilon = NV_EPSILON) + { + float l = length(v); + if (isZero(l, epsilon)) { + return fallback; + } + return scale(v, 1.0f / l); + } + + // Safe, branchless normalization from Andy Firth. All error checking ommitted. + // http://altdevblogaday.com/2011/08/21/practical-flt-point-tricks/ + inline Vector4 normalizeFast(Vector4::Arg v) + { + const float very_small_float = 1.0e-037f; + float l = very_small_float + length(v); + return scale(v, 1.0f / l); + } + + inline bool equal(Vector4::Arg v1, Vector4::Arg v2, float epsilon = NV_EPSILON) + { + return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon) && equal(v1.w, v2.w, epsilon); + } + + inline Vector4 min(Vector4::Arg a, Vector4::Arg b) + { + return Vector4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w)); + } + + inline Vector4 max(Vector4::Arg a, Vector4::Arg b) + { + return Vector4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); + } + + inline bool isValid(Vector4::Arg v) + { + return isFinite(v.x) && isFinite(v.y) && isFinite(v.z) && isFinite(v.w); + } + + inline Vector4 validate(Vector4::Arg v, Vector4::Arg fallback = Vector4(0.0f)) + { + if (!isValid(v)) return fallback; + Vector4 vf = v; + nv::floatCleanup(vf.component, 4); + return vf; + } + +} // nv namespace + +#endif // NV_MATH_VECTOR_INL diff --git a/src/nvtt/ClusterFit.cpp b/src/nvtt/ClusterFit.cpp index 1209648..d148fb1 100644 --- a/src/nvtt/ClusterFit.cpp +++ b/src/nvtt/ClusterFit.cpp @@ -26,6 +26,7 @@ #include "ClusterFit.h" #include "nvmath/Fitting.h" +#include "nvmath/Vector.inl" #include "nvimage/ColorBlock.h" #include // FLT_MAX diff --git a/src/nvtt/CubeSurface.cpp b/src/nvtt/CubeSurface.cpp index bdf574c..83f39d8 100644 --- a/src/nvtt/CubeSurface.cpp +++ b/src/nvtt/CubeSurface.cpp @@ -26,7 +26,7 @@ #include "nvimage/DirectDrawSurface.h" -#include "nvmath/Vector.h" +#include "nvmath/Vector.inl" #include "nvcore/Array.h" #include "nvcore/StrLib.h" @@ -474,7 +474,7 @@ Vector3 CubeSurface::Private::applyCosinePowerFilter(const Vector3 & filterDir, // Focal point in polar coordinates: Vector2 Fp = toPolar(F); nvCheck(Fp.y >= 0.0f); // top - nvCheck(Fp.y <= PI/2); // horizon + //nvCheck(Fp.y <= PI/2); // horizon @@ We should cull this earlier. // If this is an ellipse: if (Fp.y + coneAngle < PI/2) { diff --git a/src/nvtt/InputOptions.cpp b/src/nvtt/InputOptions.cpp index 0ff1ad6..fff9069 100644 --- a/src/nvtt/InputOptions.cpp +++ b/src/nvtt/InputOptions.cpp @@ -22,15 +22,16 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include // memcpy +#include "InputOptions.h" -#include // nextPowerOfTwo -#include +#include "nvmath/Vector.inl" + +#include "nvcore/Utils.h" // nextPowerOfTwo +#include "nvcore/Memory.h" + +#include // memcpy -#include -#include "nvtt.h" -#include "InputOptions.h" using namespace nv; using namespace nvtt; diff --git a/src/nvtt/QuickCompressDXT.cpp b/src/nvtt/QuickCompressDXT.cpp index b767823..5659cef 100644 --- a/src/nvtt/QuickCompressDXT.cpp +++ b/src/nvtt/QuickCompressDXT.cpp @@ -22,16 +22,18 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include // swap +#include "QuickCompressDXT.h" +#include "OptimalCompressDXT.h" -#include -#include +#include "nvimage/ColorBlock.h" +#include "nvimage/BlockDXT.h" -#include -#include +#include "nvmath/Color.h" +#include "nvmath/Vector.inl" +#include "nvmath/Fitting.h" + +#include "nvcore/Utils.h" // swap -#include "QuickCompressDXT.h" -#include "OptimalCompressDXT.h" using namespace nv; diff --git a/src/nvtt/Surface.cpp b/src/nvtt/Surface.cpp index 1e8fe6c..e5fb086 100644 --- a/src/nvtt/Surface.cpp +++ b/src/nvtt/Surface.cpp @@ -24,7 +24,7 @@ #include "Surface.h" -#include "nvmath/Vector.h" +#include "nvmath/Vector.inl" #include "nvmath/Matrix.h" #include "nvmath/Color.h" #include "nvmath/Half.h" diff --git a/src/nvtt/bc6h/utils.cpp b/src/nvtt/bc6h/utils.cpp index 8c557b0..bc20d2f 100644 --- a/src/nvtt/bc6h/utils.cpp +++ b/src/nvtt/bc6h/utils.cpp @@ -13,6 +13,7 @@ See the License for the specific language governing permissions and limitations // Utility and common routines #include "utils.h" +#include "nvmath/Vector.inl" #include using namespace nv; diff --git a/src/nvtt/bc6h/zohone.cpp b/src/nvtt/bc6h/zohone.cpp index f8f6b62..0cd966c 100644 --- a/src/nvtt/bc6h/zohone.cpp +++ b/src/nvtt/bc6h/zohone.cpp @@ -18,7 +18,7 @@ See the License for the specific language governing permissions and limitations #include "zoh.h" #include "utils.h" -#include "nvmath/Vector.h" +#include "nvmath/Vector.inl" #include "nvmath/Fitting.h" #include // strlen diff --git a/src/nvtt/bc6h/zohtwo.cpp b/src/nvtt/bc6h/zohtwo.cpp index 06e8436..9ae4e19 100644 --- a/src/nvtt/bc6h/zohtwo.cpp +++ b/src/nvtt/bc6h/zohtwo.cpp @@ -43,6 +43,7 @@ See the License for the specific language governing permissions and limitations #include "utils.h" #include "nvmath/Fitting.h" +#include "nvmath/Vector.inl" #include // strlen #include // FLT_MAX diff --git a/src/nvtt/cuda/CudaCompressorDXT.cpp b/src/nvtt/cuda/CudaCompressorDXT.cpp index 51a44f2..83c35ce 100644 --- a/src/nvtt/cuda/CudaCompressorDXT.cpp +++ b/src/nvtt/cuda/CudaCompressorDXT.cpp @@ -27,6 +27,7 @@ #include "nvcore/Debug.h" #include "nvmath/Color.h" +#include "nvmath/Vector.inl" #include "nvimage/Image.h" #include "nvimage/ColorBlock.h" #include "nvimage/BlockDXT.h" diff --git a/src/nvtt/tests/cubemaptest.cpp b/src/nvtt/tests/cubemaptest.cpp index 8ad16bd..e1c87ed 100644 --- a/src/nvtt/tests/cubemaptest.cpp +++ b/src/nvtt/tests/cubemaptest.cpp @@ -40,9 +40,12 @@ int main(int argc, char *argv[]) // Init context. nvtt::Context context; + const char * fileName = "envmap.dds"; + if (argc > 1) fileName = argv[1]; + // Load cubemap. nvtt::CubeSurface envmap; - if (!envmap.load("envmap.dds", 0)) { + if (!envmap.load(fileName, 0)) { printf("Error loading envmap.dds\n"); return EXIT_FAILURE; } diff --git a/src/nvtt/tools/imgdiff.cpp b/src/nvtt/tools/imgdiff.cpp index bc9d98b..bc00fb5 100644 --- a/src/nvtt/tools/imgdiff.cpp +++ b/src/nvtt/tools/imgdiff.cpp @@ -21,18 +21,19 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -#include -#include +#include "cmdline.h" + +#include "nvmath/Color.h" +#include "nvmath/Vector.inl" -#include -#include +#include "nvimage/Image.h" +#include "nvimage/DirectDrawSurface.h" -#include -#include +#include "nvcore/StrLib.h" +#include "nvcore/StdStream.h" #include -#include "cmdline.h" static bool loadImage(nv::Image & image, const char * fileName) {