From a9d0a22233e800e70bc1fa96f33c3845c3914d63 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Nov 2024 18:58:20 +0000 Subject: [PATCH 01/26] Added CoordinateFrame a ucoord classes. --- include/vsg/all.h | 1 + include/vsg/app/RecordTraversal.h | 2 + include/vsg/core/ConstVisitor.h | 6 +- include/vsg/core/Visitor.h | 6 +- include/vsg/maths/ucoord.h | 142 ++++++++++++++++++++++++++++ include/vsg/nodes/CoordinateFrame.h | 43 +++++++++ src/vsg/CMakeLists.txt | 1 + src/vsg/app/RecordTraversal.cpp | 23 +++++ src/vsg/core/ConstVisitor.cpp | 4 + src/vsg/core/Visitor.cpp | 4 + src/vsg/io/ObjectFactory.cpp | 1 + src/vsg/nodes/CoordinateFrame.cpp | 58 ++++++++++++ 12 files changed, 287 insertions(+), 4 deletions(-) create mode 100644 include/vsg/maths/ucoord.h create mode 100644 include/vsg/nodes/CoordinateFrame.h create mode 100644 src/vsg/nodes/CoordinateFrame.cpp diff --git a/include/vsg/all.h b/include/vsg/all.h index 4f2fd080d..0bcc75651 100644 --- a/include/vsg/all.h +++ b/include/vsg/all.h @@ -60,6 +60,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include diff --git a/include/vsg/app/RecordTraversal.h b/include/vsg/app/RecordTraversal.h index 25c27b0ab..4cd934cd6 100644 --- a/include/vsg/app/RecordTraversal.h +++ b/include/vsg/app/RecordTraversal.h @@ -36,6 +36,7 @@ namespace vsg class Layer; class Transform; class MatrixTransform; + class CoordinateFrame; class Joint; class TileDatabase; class VertexDraw; @@ -135,6 +136,7 @@ namespace vsg // transform nodes void apply(const Transform& transform); void apply(const MatrixTransform& mt); + void apply(const CoordinateFrame& cf); // Animation nodes void apply(const Joint& joint); diff --git a/include/vsg/core/ConstVisitor.h b/include/vsg/core/ConstVisitor.h index 841d15ebb..0de8d4b0a 100644 --- a/include/vsg/core/ConstVisitor.h +++ b/include/vsg/core/ConstVisitor.h @@ -34,8 +34,9 @@ namespace vsg class StateGroup; class CullGroup; class CullNode; - class MatrixTransform; class Transform; + class MatrixTransform; + class CoordinateFrame; class Geometry; class VertexDraw; class VertexIndexDraw; @@ -323,8 +324,9 @@ namespace vsg virtual void apply(const StateGroup&); virtual void apply(const CullGroup&); virtual void apply(const CullNode&); - virtual void apply(const MatrixTransform&); virtual void apply(const Transform&); + virtual void apply(const MatrixTransform&); + virtual void apply(const CoordinateFrame&); virtual void apply(const Geometry&); virtual void apply(const VertexDraw&); virtual void apply(const VertexIndexDraw&); diff --git a/include/vsg/core/Visitor.h b/include/vsg/core/Visitor.h index 93a9ae31c..98977bbd6 100644 --- a/include/vsg/core/Visitor.h +++ b/include/vsg/core/Visitor.h @@ -34,8 +34,9 @@ namespace vsg class StateGroup; class CullGroup; class CullNode; - class MatrixTransform; class Transform; + class MatrixTransform; + class CoordinateFrame; class Geometry; class VertexDraw; class VertexIndexDraw; @@ -323,8 +324,9 @@ namespace vsg virtual void apply(StateGroup&); virtual void apply(CullGroup&); virtual void apply(CullNode&); - virtual void apply(MatrixTransform&); virtual void apply(Transform&); + virtual void apply(MatrixTransform&); + virtual void apply(CoordinateFrame&); virtual void apply(Geometry&); virtual void apply(VertexDraw&); virtual void apply(VertexIndexDraw&); diff --git a/include/vsg/maths/ucoord.h b/include/vsg/maths/ucoord.h new file mode 100644 index 000000000..97f0b8b38 --- /dev/null +++ b/include/vsg/maths/ucoord.h @@ -0,0 +1,142 @@ +#pragma once + +/* + +Copyright(c) 2018 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +// we can't implement the anonymous union/structs combination without causing warnings, so disable them for just this header +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpedantic" +#endif +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" +# pragma clang diagnostic ignored "-Wnested-anon-types" +#endif + +#include + +namespace vsg +{ + + /// ucoord class for managing astronomical scale coordinates + struct ucoord + { + using value_type = double; + using vec_type = t_vec3; + + vec_type origin; + vec_type offset; + + constexpr ucoord() {} + + constexpr ucoord(const ucoord& uc) = default; + constexpr ucoord(value_type in_x, value_type in_y, value_type in_z) : + origin(0.0, 0.0, 0.0), + offset(in_x, in_y, in_z) {} + template + constexpr explicit ucoord(const t_vec3& v) : + origin(0.0, 0.0, 0.0), + offset(static_cast(v.x), static_cast(v.y), static_cast(v.z)) {} + template + constexpr ucoord(const t_vec3& in_origin, const t_vec3& in_offset) : + origin(in_origin), + offset(in_offset){} + + ucoord& operator=(const ucoord& rhs) + { + origin = rhs.origin; + offset = rhs.offset; + return *this; + } + + void set(value_type in_x, value_type in_y, value_type in_z) + { + origin.set(in_x, in_y, in_z); + offset.set(in_x, in_y, in_z); + } + + inline ucoord& operator+=(const ucoord& rhs) + { + origin += rhs.origin; + offset += rhs.offset; + return *this; + } + + inline ucoord& operator-=(const ucoord& rhs) + { + origin -= rhs.origin; + offset -= rhs.offset; + return *this; + } + + explicit operator bool() const noexcept { return origin || offset; } + }; + + VSG_type_name(vsg::ucoord); + + inline constexpr bool operator==(const ucoord& lhs, const ucoord& rhs) + { + return lhs.origin == rhs.origin && lhs.offset == rhs.offset; + } + + inline constexpr bool operator!=(const ucoord& lhs, const ucoord& rhs) + { + return lhs.origin != rhs.origin || lhs.offset != rhs.offset; + } + + inline bool operator<(const ucoord& lhs, const ucoord& rhs) + { + ucoord::vec_type delta = (rhs.origin-lhs.origin) + (rhs.offset - lhs.offset); + if (delta[0] < 0.0) return true; + if (delta[0] > 0.0) return false; + if (delta[1] < 0.0) return true; + if (delta[1] > 0.0) return false; + return (delta[2] < 0.0); + } + + inline constexpr ucoord operator-(const ucoord& lhs, const ucoord& rhs) + { + return ucoord(lhs.origin - rhs.origin, lhs.offset - rhs.offset); + } + + inline constexpr ucoord operator+(const ucoord& lhs, const ucoord& rhs) + { + return ucoord(lhs.origin + rhs.origin, lhs.offset + rhs.offset); + } + + inline constexpr ucoord::value_type length(const ucoord& uc) + { + return length(uc.origin + uc.offset); + } + + inline constexpr ucoord::value_type length2(const ucoord& uc) + { + return length2(uc.origin + uc.offset); + } + + constexpr ucoord mix(const ucoord& start, const ucoord& end, ucoord::value_type r) + { + ucoord::value_type one_minus_r = 1.0 - r; + return ucoord(start.origin * one_minus_r + start.origin * r, + start.offset * one_minus_r + end.offset * r); + } + + +} // namespace vsg + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h new file mode 100644 index 000000000..8b8630a15 --- /dev/null +++ b/include/vsg/nodes/CoordinateFrame.h @@ -0,0 +1,43 @@ +#pragma once + +/* + +Copyright(c) 2018 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include + +namespace vsg +{ + + /// CoordinateFrame provides support for astronomically large coordinates + class VSG_DECLSPEC CoordinateFrame : public Inherit + { + public: + CoordinateFrame(); + CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop = {}); + + ucoord::vec_type origin; + + dmat4 transform(const dmat4& mv) const override; + + public: + ref_ptr clone(const CopyOp& copyop = {}) const override { return CoordinateFrame::create(*this, copyop); } + int compare(const Object& rhs) const override; + + void read(Input& input) override; + void write(Output& output) const override; + + protected: + }; + VSG_type_name(vsg::CoordinateFrame); + +} // namespace vsg diff --git a/src/vsg/CMakeLists.txt b/src/vsg/CMakeLists.txt index 63fe899e9..0ddb87a7c 100644 --- a/src/vsg/CMakeLists.txt +++ b/src/vsg/CMakeLists.txt @@ -34,6 +34,7 @@ set(SOURCES nodes/PagedLOD.cpp nodes/AbsoluteTransform.cpp nodes/MatrixTransform.cpp + nodes/CoordinateFrame.cpp nodes/Transform.cpp nodes/VertexDraw.cpp nodes/VertexIndexDraw.cpp diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index acdd0d560..bb0316c65 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -35,6 +35,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include @@ -435,6 +436,28 @@ void RecordTraversal::apply(const MatrixTransform& mt) _state->dirty = true; } +void RecordTraversal::apply(const CoordinateFrame& cf) +{ + GPU_INSTRUMENTATION_L2_NCO(instrumentation, *getCommandBuffer(), "CoordinateFrame", COLOR_RECORD_L2, &cf); + + _state->modelviewMatrixStack.push(cf); + _state->dirty = true; + + if (cf.subgraphRequiresLocalFrustum) + { + _state->pushFrustum(); + cf.traverse(*this); + _state->popFrustum(); + } + else + { + cf.traverse(*this); + } + + _state->modelviewMatrixStack.pop(); + _state->dirty = true; +} + // Animation nodes void RecordTraversal::apply(const Joint&) { diff --git a/src/vsg/core/ConstVisitor.cpp b/src/vsg/core/ConstVisitor.cpp index cc2d578f0..3c85f747c 100644 --- a/src/vsg/core/ConstVisitor.cpp +++ b/src/vsg/core/ConstVisitor.cpp @@ -573,6 +573,10 @@ void ConstVisitor::apply(const MatrixTransform& value) { apply(static_cast(value)); } +void ConstVisitor::apply(const CoordinateFrame& value) +{ + apply(static_cast(value)); +} void ConstVisitor::apply(const Geometry& value) { apply(static_cast(value)); diff --git a/src/vsg/core/Visitor.cpp b/src/vsg/core/Visitor.cpp index 6d5497f9d..a2482e5f4 100644 --- a/src/vsg/core/Visitor.cpp +++ b/src/vsg/core/Visitor.cpp @@ -573,6 +573,10 @@ void Visitor::apply(MatrixTransform& value) { apply(static_cast(value)); } +void Visitor::apply(CoordinateFrame& value) +{ + apply(static_cast(value)); +} void Visitor::apply(Geometry& value) { apply(static_cast(value)); diff --git a/src/vsg/io/ObjectFactory.cpp b/src/vsg/io/ObjectFactory.cpp index b7fd6cd93..ad490db6a 100644 --- a/src/vsg/io/ObjectFactory.cpp +++ b/src/vsg/io/ObjectFactory.cpp @@ -176,6 +176,7 @@ ObjectFactory::ObjectFactory() add(); add(); add(); + add(); add(); add(); add(); diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp new file mode 100644 index 000000000..32d1ff50f --- /dev/null +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -0,0 +1,58 @@ +/* + +Copyright(c) 2018 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include +#include +#include + +using namespace vsg; + +CoordinateFrame::CoordinateFrame() +{ +} + +CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop) : + Inherit(rhs, copyop), + origin(rhs.origin) +{ +} + +int CoordinateFrame::compare(const Object& rhs_object) const +{ + int result = Transform::compare(rhs_object); + if (result != 0) return result; + + const auto& rhs = static_cast(rhs_object); + return compare_value(origin, rhs.origin); +} + +void CoordinateFrame::read(Input& input) +{ + Node::read(input); + input.read("origin", origin); + input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); + input.readObjects("children", children); +} + +void CoordinateFrame::write(Output& output) const +{ + Node::write(output); + output.write("origin", origin); + output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); + output.writeObjects("children", children); +} + +dmat4 CoordinateFrame::transform(const dmat4& mv) const +{ + return mv * translate(origin); +} From c42891417a0ad2f27992ebca6425a487d2329e6b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 13 Nov 2024 16:48:02 +0000 Subject: [PATCH 02/26] Added name to CoordinateFrame class --- include/vsg/nodes/CoordinateFrame.h | 1 + src/vsg/nodes/CoordinateFrame.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 8b8630a15..266539e21 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -25,6 +25,7 @@ namespace vsg CoordinateFrame(); CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop = {}); + std::string name; ucoord::vec_type origin; dmat4 transform(const dmat4& mv) const override; diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 32d1ff50f..7c7f6669a 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -23,6 +23,7 @@ CoordinateFrame::CoordinateFrame() CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop) : Inherit(rhs, copyop), + name(rhs.name), origin(rhs.origin) { } @@ -33,12 +34,14 @@ int CoordinateFrame::compare(const Object& rhs_object) const if (result != 0) return result; const auto& rhs = static_cast(rhs_object); + if ((result = compare_value(name, rhs.name)) != 0) return result; return compare_value(origin, rhs.origin); } void CoordinateFrame::read(Input& input) { Node::read(input); + input.read("name", name); input.read("origin", origin); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); @@ -47,6 +50,7 @@ void CoordinateFrame::read(Input& input) void CoordinateFrame::write(Output& output) const { Node::write(output); + output.write("name", name); output.write("origin", origin); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); From 807b19189dddaac448f37cd35a632dfb00d71201 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 14 Nov 2024 14:04:51 +0000 Subject: [PATCH 03/26] Added support for ViewMatrix::origin to help support astronomically large scene graphs. To be used in combination with CoordinateFrame::origin. --- include/vsg/app/ViewMatrix.h | 36 +++++++++++++-------------------- src/vsg/app/RecordTraversal.cpp | 6 +++++- src/vsg/app/ViewMatrix.cpp | 32 +++++++++++++++++++++++++---- 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/include/vsg/app/ViewMatrix.h b/include/vsg/app/ViewMatrix.h index c026aaca0..cdc4ca700 100644 --- a/include/vsg/app/ViewMatrix.h +++ b/include/vsg/app/ViewMatrix.h @@ -31,11 +31,16 @@ namespace vsg { } - virtual dmat4 transform() const = 0; + /// origin value provides a means of translating the view matrix relative to the origin of any CoordinateFrame subgraphs + /// to maximize the precision when moving around the CoordinateFrame subgraph. This is helpful for astronmically large + /// scenes where standrd double precision is insufficient for avoiding visually significant numerical errors. + dvec3 origin; - virtual dmat4 inverse() const + virtual dmat4 transform(const vsg::dvec3& offset={}) const = 0; + + virtual dmat4 inverse(const vsg::dvec3& offset={}) const { - return vsg::inverse(transform()); + return vsg::inverse(transform(offset)); } }; VSG_type_name(vsg::ViewMatrix); @@ -79,21 +84,11 @@ namespace vsg ref_ptr clone(const CopyOp& copyop = {}) const override { return LookAt::create(*this, copyop); } - void transform(const dmat4& matrix) - { - up = normalize(matrix * (eye + up) - matrix * eye); - center = matrix * center; - eye = matrix * eye; - } + void transform(const dmat4& matrix); - void set(const dmat4& matrix) - { - up = normalize(matrix * (dvec3(0.0, 0.0, 0.0) + dvec3(0.0, 1.0, 0.0)) - matrix * dvec3(0.0, 0.0, 0.0)); - center = matrix * dvec3(0.0, 0.0, -1.0); - eye = matrix * dvec3(0.0, 0.0, 0.0); - } + void set(const dmat4& matrix); - dmat4 transform() const override { return lookAt(eye, center, up); } + dmat4 transform(const vsg::dvec3& offset={}) const override; void read(Input& input) override; void write(Output& output) const override; @@ -115,10 +110,7 @@ namespace vsg } /// returns matrix * viewMatrix->transform() - dmat4 transform() const override - { - return matrix * viewMatrix->transform(); - } + dmat4 transform(const vsg::dvec3& offset={}) const override; dmat4 matrix; ref_ptr viewMatrix; @@ -141,8 +133,8 @@ namespace vsg objectPath(path.begin(), path.end()) {} /// returns matrix * computeTransfrom(objectPath) - dmat4 transform() const override; - dmat4 inverse() const override; + dmat4 transform(const vsg::dvec3& offset={}) const override; + dmat4 inverse(const vsg::dvec3& offset={}) const override; dmat4 matrix; RefObjectPath objectPath; diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index bb0316c65..e3d91d525 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -440,7 +440,11 @@ void RecordTraversal::apply(const CoordinateFrame& cf) { GPU_INSTRUMENTATION_L2_NCO(instrumentation, *getCommandBuffer(), "CoordinateFrame", COLOR_RECORD_L2, &cf); - _state->modelviewMatrixStack.push(cf); + View* parentView = _viewDependentState ? _viewDependentState->view : nullptr; + Camera* camera = parentView ? parentView->camera : nullptr; + ViewMatrix* viewMatrix = camera ? camera->viewMatrix : nullptr; + + _state->modelviewMatrixStack.push(viewMatrix->transform(cf.origin)); _state->dirty = true; if (cf.subgraphRequiresLocalFrustum) diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 7c110eeef..5df8c3b43 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -34,12 +34,36 @@ void LookAt::write(Output& output) const output.write("up", up); } -dmat4 TrackingViewMatrix::transform() const +void LookAt::transform(const dmat4& matrix) { - return matrix * vsg::inverse(computeTransform(objectPath)); + up = normalize(matrix * (eye + up) - matrix * eye); + center = matrix * center; + eye = matrix * eye; } -dmat4 TrackingViewMatrix::inverse() const +void LookAt::set(const dmat4& matrix) { - return computeTransform(objectPath) * vsg::inverse(matrix); + up = normalize(matrix * (dvec3(0.0, 0.0, 0.0) + dvec3(0.0, 1.0, 0.0)) - matrix * dvec3(0.0, 0.0, 0.0)); + center = matrix * dvec3(0.0, 0.0, -1.0); + eye = matrix * dvec3(0.0, 0.0, 0.0); +} + +dmat4 LookAt::transform(const vsg::dvec3& offset) const +{ + return lookAt(eye, center, up) * vsg::translate(offset-origin); +} + +dmat4 RelativeViewMatrix::transform(const vsg::dvec3& offset) const +{ + return matrix * viewMatrix->transform(offset); +} + +dmat4 TrackingViewMatrix::transform(const vsg::dvec3& offset) const +{ + return matrix * vsg::translate(offset-origin) * vsg::inverse(computeTransform(objectPath)); +} + +dmat4 TrackingViewMatrix::inverse(const vsg::dvec3& offset) const +{ + return computeTransform(objectPath) * vsg::translate(origin - offset) * vsg::inverse(matrix); } From 7e6c315a09c5839e92ded6b9ce67e2cfa09febca Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Nov 2024 11:57:38 +0000 Subject: [PATCH 04/26] Fixed the LookAt handling of offset and origin. --- src/vsg/app/ViewMatrix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 5df8c3b43..121336fc5 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -50,7 +50,8 @@ void LookAt::set(const dmat4& matrix) dmat4 LookAt::transform(const vsg::dvec3& offset) const { - return lookAt(eye, center, up) * vsg::translate(offset-origin); + dvec3 delta = origin - offset; + return lookAt(eye + delta, center + delta, up); } dmat4 RelativeViewMatrix::transform(const vsg::dvec3& offset) const From f41d9ca3a1f3cf137f38f97d32b602e5c08df392 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Nov 2024 14:52:52 +0000 Subject: [PATCH 05/26] Added vsg::LookDirection ViewMatrix implementation. --- include/vsg/app/ViewMatrix.h | 34 ++++++++++++++++++++++++++++++++-- src/vsg/app/ViewMatrix.cpp | 23 +++++++++++++++++------ 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/include/vsg/app/ViewMatrix.h b/include/vsg/app/ViewMatrix.h index cdc4ca700..41c41b43a 100644 --- a/include/vsg/app/ViewMatrix.h +++ b/include/vsg/app/ViewMatrix.h @@ -88,7 +88,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const vsg::dvec3& offset={}) const override; + dmat4 transform(const dvec3& offset={}) const override; void read(Input& input) override; void write(Output& output) const override; @@ -99,8 +99,38 @@ namespace vsg }; VSG_type_name(vsg::LookAt); + /// LookDirection is a ViewMatrix that uses a position and rotation to set the view matrix. + class VSG_DECLSPEC LookDirection : public vsg::Inherit + { + public: + + LookDirection() : + position(0.0, 0.0, 0.0), + rotation() + { + } + + LookDirection(const LookDirection& view, const CopyOp& copyop = {}) : + Inherit(view, copyop), + position(view.position), + rotation(view.rotation) + { + } + + ref_ptr clone(const CopyOp& copyop = {}) const override { return LookDirection::create(*this, copyop); } + + dvec3 position; + dquat rotation; + + void set(const dmat4& matrix); + + dmat4 transform(const dvec3& offset={}) const override; + }; + VSG_type_name(vsg::LookDirection); + + /// RelativeViewMatrix is a ViewMatrix that decorates another ViewMatrix and pre-multiplies its transform matrix to give a relative view matrix. - class RelativeViewMatrix : public Inherit + class VSG_DECLSPEC RelativeViewMatrix : public Inherit { public: RelativeViewMatrix(const dmat4& m, ref_ptr vm) : diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 121336fc5..8c77d74d4 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -48,23 +48,34 @@ void LookAt::set(const dmat4& matrix) eye = matrix * dvec3(0.0, 0.0, 0.0); } -dmat4 LookAt::transform(const vsg::dvec3& offset) const +dmat4 LookAt::transform(const dvec3& offset) const { dvec3 delta = origin - offset; - return lookAt(eye + delta, center + delta, up); + return vsg::lookAt(eye + delta, center + delta, up); } -dmat4 RelativeViewMatrix::transform(const vsg::dvec3& offset) const +void LookDirection::set(const dmat4& matrix) +{ + dvec3 scale; + vsg::decompose(matrix, position, rotation, scale); +} + +dmat4 LookDirection::transform(const dvec3& offset) const +{ + return vsg::rotate(-rotation) * vsg::translate(offset-origin-position); +} + +dmat4 RelativeViewMatrix::transform(const dvec3& offset) const { return matrix * viewMatrix->transform(offset); } -dmat4 TrackingViewMatrix::transform(const vsg::dvec3& offset) const +dmat4 TrackingViewMatrix::transform(const dvec3& offset) const { return matrix * vsg::translate(offset-origin) * vsg::inverse(computeTransform(objectPath)); } -dmat4 TrackingViewMatrix::inverse(const vsg::dvec3& offset) const +dmat4 TrackingViewMatrix::inverse(const dvec3& offset) const { - return computeTransform(objectPath) * vsg::translate(origin - offset) * vsg::inverse(matrix); + return vsg::computeTransform(objectPath) * vsg::translate(origin - offset) * vsg::inverse(matrix); } From ac880ea1b2a7867cd5dabdb3690d298d99ba451f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Nov 2024 13:45:36 +0000 Subject: [PATCH 06/26] Added catch of nullptr viewMatrix --- cmake/cppcheck-suppression-list.txt | 1 + src/vsg/app/RecordTraversal.cpp | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index da95dacf6..4a7735e9e 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -208,6 +208,7 @@ shadowFunction:*/src/vsg/state/DescriptorImage.cpp shadowFunction:*/src/vsg/utils/FindDynamicObjects.cpp shadowFunction:*/src/vsg/utils/LoadPagedLOD.cpp shadowFunction:*/src/vsg/utils/PropagateDynamicObjects.cpp +shadowFunction:*/src/vsg/app/ViewMatrix.cpp // suppress unhelpful warning of c casts cstyleCast:*/include/vsg/io/mem_stream.h diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index e3d91d525..e00555862 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -444,7 +444,15 @@ void RecordTraversal::apply(const CoordinateFrame& cf) Camera* camera = parentView ? parentView->camera : nullptr; ViewMatrix* viewMatrix = camera ? camera->viewMatrix : nullptr; - _state->modelviewMatrixStack.push(viewMatrix->transform(cf.origin)); + if (viewMatrix) + { + _state->modelviewMatrixStack.push(viewMatrix->transform(cf.origin)); + } + else + { + _state->modelviewMatrixStack.push(cf); + } + _state->dirty = true; if (cf.subgraphRequiresLocalFrustum) From 52d326253220215553f4eb490a8c073c68c74e3c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Nov 2024 16:27:40 +0000 Subject: [PATCH 07/26] cppcheck warning fix. --- src/vsg/app/RecordTraversal.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index e00555862..b084978ac 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -440,9 +440,9 @@ void RecordTraversal::apply(const CoordinateFrame& cf) { GPU_INSTRUMENTATION_L2_NCO(instrumentation, *getCommandBuffer(), "CoordinateFrame", COLOR_RECORD_L2, &cf); - View* parentView = _viewDependentState ? _viewDependentState->view : nullptr; - Camera* camera = parentView ? parentView->camera : nullptr; - ViewMatrix* viewMatrix = camera ? camera->viewMatrix : nullptr; + const View* parentView = _viewDependentState ? _viewDependentState->view : nullptr; + const Camera* camera = parentView ? parentView->camera : nullptr; + const ViewMatrix* viewMatrix = camera ? camera->viewMatrix : nullptr; if (viewMatrix) { From d7e814651b4692b0d39442ab73e766fce875eb1f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Nov 2024 18:39:46 +0000 Subject: [PATCH 08/26] Removed ucoord as it's no longer required for CoordinateFrame. --- include/vsg/maths/ucoord.h | 142 ---------------------------- include/vsg/nodes/CoordinateFrame.h | 3 +- 2 files changed, 1 insertion(+), 144 deletions(-) delete mode 100644 include/vsg/maths/ucoord.h diff --git a/include/vsg/maths/ucoord.h b/include/vsg/maths/ucoord.h deleted file mode 100644 index 97f0b8b38..000000000 --- a/include/vsg/maths/ucoord.h +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once - -/* - -Copyright(c) 2018 Robert Osfield - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -// we can't implement the anonymous union/structs combination without causing warnings, so disable them for just this header -#if defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpedantic" -#endif -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wgnu-anonymous-struct" -# pragma clang diagnostic ignored "-Wnested-anon-types" -#endif - -#include - -namespace vsg -{ - - /// ucoord class for managing astronomical scale coordinates - struct ucoord - { - using value_type = double; - using vec_type = t_vec3; - - vec_type origin; - vec_type offset; - - constexpr ucoord() {} - - constexpr ucoord(const ucoord& uc) = default; - constexpr ucoord(value_type in_x, value_type in_y, value_type in_z) : - origin(0.0, 0.0, 0.0), - offset(in_x, in_y, in_z) {} - template - constexpr explicit ucoord(const t_vec3& v) : - origin(0.0, 0.0, 0.0), - offset(static_cast(v.x), static_cast(v.y), static_cast(v.z)) {} - template - constexpr ucoord(const t_vec3& in_origin, const t_vec3& in_offset) : - origin(in_origin), - offset(in_offset){} - - ucoord& operator=(const ucoord& rhs) - { - origin = rhs.origin; - offset = rhs.offset; - return *this; - } - - void set(value_type in_x, value_type in_y, value_type in_z) - { - origin.set(in_x, in_y, in_z); - offset.set(in_x, in_y, in_z); - } - - inline ucoord& operator+=(const ucoord& rhs) - { - origin += rhs.origin; - offset += rhs.offset; - return *this; - } - - inline ucoord& operator-=(const ucoord& rhs) - { - origin -= rhs.origin; - offset -= rhs.offset; - return *this; - } - - explicit operator bool() const noexcept { return origin || offset; } - }; - - VSG_type_name(vsg::ucoord); - - inline constexpr bool operator==(const ucoord& lhs, const ucoord& rhs) - { - return lhs.origin == rhs.origin && lhs.offset == rhs.offset; - } - - inline constexpr bool operator!=(const ucoord& lhs, const ucoord& rhs) - { - return lhs.origin != rhs.origin || lhs.offset != rhs.offset; - } - - inline bool operator<(const ucoord& lhs, const ucoord& rhs) - { - ucoord::vec_type delta = (rhs.origin-lhs.origin) + (rhs.offset - lhs.offset); - if (delta[0] < 0.0) return true; - if (delta[0] > 0.0) return false; - if (delta[1] < 0.0) return true; - if (delta[1] > 0.0) return false; - return (delta[2] < 0.0); - } - - inline constexpr ucoord operator-(const ucoord& lhs, const ucoord& rhs) - { - return ucoord(lhs.origin - rhs.origin, lhs.offset - rhs.offset); - } - - inline constexpr ucoord operator+(const ucoord& lhs, const ucoord& rhs) - { - return ucoord(lhs.origin + rhs.origin, lhs.offset + rhs.offset); - } - - inline constexpr ucoord::value_type length(const ucoord& uc) - { - return length(uc.origin + uc.offset); - } - - inline constexpr ucoord::value_type length2(const ucoord& uc) - { - return length2(uc.origin + uc.offset); - } - - constexpr ucoord mix(const ucoord& start, const ucoord& end, ucoord::value_type r) - { - ucoord::value_type one_minus_r = 1.0 - r; - return ucoord(start.origin * one_minus_r + start.origin * r, - start.offset * one_minus_r + end.offset * r); - } - - -} // namespace vsg - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -#if defined(__GNUC__) -# pragma GCC diagnostic pop -#endif diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 266539e21..36fef0cec 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -13,7 +13,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #include -#include namespace vsg { @@ -26,7 +25,7 @@ namespace vsg CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop = {}); std::string name; - ucoord::vec_type origin; + dvec3 origin; dmat4 transform(const dmat4& mv) const override; From 2e42b7a6af95c899d85428ba2d356f5d8e83d445 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Nov 2024 17:04:06 +0000 Subject: [PATCH 09/26] Added long double versions of various maths classes/functions. --- include/vsg/maths/box.h | 2 ++ include/vsg/maths/mat4.h | 2 ++ include/vsg/maths/plane.h | 1 + include/vsg/maths/quat.h | 2 ++ include/vsg/maths/sphere.h | 2 ++ include/vsg/maths/transform.h | 5 +++++ include/vsg/maths/vec2.h | 1 + include/vsg/maths/vec3.h | 2 ++ include/vsg/maths/vec4.h | 2 ++ src/vsg/maths/maths_transform.cpp | 5 +++++ 10 files changed, 24 insertions(+) diff --git a/include/vsg/maths/box.h b/include/vsg/maths/box.h index 46d47a999..538ab72ae 100644 --- a/include/vsg/maths/box.h +++ b/include/vsg/maths/box.h @@ -90,9 +90,11 @@ namespace vsg using box = t_box; /// float box class using dbox = t_box; /// double box class + using ldbox = t_box; /// double box class VSG_type_name(vsg::box); VSG_type_name(vsg::dbox); + VSG_type_name(vsg::ldbox); template constexpr bool operator==(const t_box& lhs, const t_box& rhs) diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index 589ea1ff0..ef3b1410a 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -121,9 +121,11 @@ namespace vsg using mat4 = t_mat4; /// float 4x4 matrix using dmat4 = t_mat4; /// double 4x4 matrix + using ldmat4 = t_mat4; /// long double 4x4 matrix VSG_type_name(vsg::mat4); VSG_type_name(vsg::dmat4); + VSG_type_name(vsg::ldmat4); template bool operator==(const t_mat4& lhs, const t_mat4& rhs) diff --git a/include/vsg/maths/plane.h b/include/vsg/maths/plane.h index da3522e96..89456a0b3 100644 --- a/include/vsg/maths/plane.h +++ b/include/vsg/maths/plane.h @@ -110,6 +110,7 @@ namespace vsg using plane = t_plane; using dplane = t_plane; + using ldplane = t_plane; VSG_type_name(vsg::plane); VSG_type_name(vsg::dplane); diff --git a/include/vsg/maths/quat.h b/include/vsg/maths/quat.h index e80456b33..5d831e19f 100644 --- a/include/vsg/maths/quat.h +++ b/include/vsg/maths/quat.h @@ -147,9 +147,11 @@ namespace vsg using quat = t_quat; /// float quaternion using dquat = t_quat; /// double quaternion + using ldquat = t_quat; /// long double quaternion VSG_type_name(vsg::quat); VSG_type_name(vsg::dquat); + VSG_type_name(vsg::ldquat); template constexpr bool operator==(const t_quat& lhs, const t_quat& rhs) diff --git a/include/vsg/maths/sphere.h b/include/vsg/maths/sphere.h index acc0054aa..23714aec3 100644 --- a/include/vsg/maths/sphere.h +++ b/include/vsg/maths/sphere.h @@ -122,9 +122,11 @@ namespace vsg using sphere = t_sphere; /// float sphere class using dsphere = t_sphere; /// double sphere class + using ldsphere = t_sphere; /// long double sphere class VSG_type_name(vsg::sphere); VSG_type_name(vsg::dsphere); + VSG_type_name(vsg::ldsphere); template constexpr bool operator==(const t_sphere& lhs, const t_sphere& rhs) diff --git a/include/vsg/maths/transform.h b/include/vsg/maths/transform.h index 2ede4463e..bd979e79b 100644 --- a/include/vsg/maths/transform.h +++ b/include/vsg/maths/transform.h @@ -248,6 +248,11 @@ namespace vsg /// assumes matrix has no skew or perspective components extern VSG_DECLSPEC bool decompose(const dmat4& m, dvec3& translation, dquat& rotation, dvec3& scale); + /// decompose long double matrix into translation, rotation and scale components. + /// maps to TRS form: vsg::translate(translation) * vsg::rotate(rotation) * vsg::scale(scale); + /// assumes matrix has no skew or perspective components + extern VSG_DECLSPEC bool decompose(const ldmat4& m, ldvec3& translation, ldquat& rotation, ldvec3& scale); + /// compute the bounding sphere that encloses a frustum defined by specified float ModelViewMatrixProjection extern VSG_DECLSPEC sphere computeFrustumBound(const mat4& m); diff --git a/include/vsg/maths/vec2.h b/include/vsg/maths/vec2.h index 47a4569af..1f789641f 100644 --- a/include/vsg/maths/vec2.h +++ b/include/vsg/maths/vec2.h @@ -138,6 +138,7 @@ namespace vsg using vec2 = t_vec2; // float 2D vector using dvec2 = t_vec2; // double 2D vector + using ldvec2 = t_vec2; // long double 2D vector using bvec2 = t_vec2; // signed 8 bit integer 2D vector using svec2 = t_vec2; // signed 16 bit integer 2D vector using ivec2 = t_vec2; // signed 32 bit integer 2D vector diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index aede3da74..3d927f91f 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -146,6 +146,7 @@ namespace vsg using vec3 = t_vec3; // float 3D vector using dvec3 = t_vec3; // double 3D vector + using ldvec3 = t_vec3; // long double 3D vector using bvec3 = t_vec3; // signed 8 bit integer 3D vector using svec3 = t_vec3; // signed 16 bit integer 3D vector using ivec3 = t_vec3; // signed 32 bit integer 3D vector @@ -155,6 +156,7 @@ namespace vsg VSG_type_name(vsg::vec3); VSG_type_name(vsg::dvec3); + VSG_type_name(vsg::ldvec3); VSG_type_name(vsg::bvec3); VSG_type_name(vsg::svec3); VSG_type_name(vsg::ivec3); diff --git a/include/vsg/maths/vec4.h b/include/vsg/maths/vec4.h index 831d286fa..149c3009c 100644 --- a/include/vsg/maths/vec4.h +++ b/include/vsg/maths/vec4.h @@ -176,6 +176,7 @@ namespace vsg using vec4 = t_vec4; // float 4D vector using dvec4 = t_vec4; // double 4D vector + using ldvec4 = t_vec4; // long double 4D vector using bvec4 = t_vec4; // signed 8 bit integer 4D vector using svec4 = t_vec4; // signed 16 bit integer 4D vector using ivec4 = t_vec4; // signed 32 bit integer 4D vector @@ -185,6 +186,7 @@ namespace vsg VSG_type_name(vsg::vec4); VSG_type_name(vsg::dvec4); + VSG_type_name(vsg::ldvec4); VSG_type_name(vsg::bvec4); VSG_type_name(vsg::svec4); VSG_type_name(vsg::ivec4); diff --git a/src/vsg/maths/maths_transform.cpp b/src/vsg/maths/maths_transform.cpp index ab543c45a..f7b8074a0 100644 --- a/src/vsg/maths/maths_transform.cpp +++ b/src/vsg/maths/maths_transform.cpp @@ -297,6 +297,11 @@ bool vsg::decompose(const dmat4& m, dvec3& translation, dquat& rotation, dvec3& return t_decompose(m, translation, rotation, scale); } +bool vsg::decompose(const ldmat4& m, ldvec3& translation, ldquat& rotation, ldvec3& scale) +{ + return t_decompose(m, translation, rotation, scale); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // // computeFrustumBound From e24a0b4c0cab6d07b99ee12b51171cc17964e475 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Nov 2024 09:12:25 +0000 Subject: [PATCH 10/26] Ran clang-format --- include/vsg/app/ViewMatrix.h | 16 +++++++--------- include/vsg/core/Array3D.h | 4 ++-- include/vsg/maths/box.h | 4 ++-- include/vsg/maths/mat4.h | 4 ++-- include/vsg/maths/quat.h | 4 ++-- include/vsg/maths/sphere.h | 4 ++-- include/vsg/maths/vec2.h | 18 +++++++++--------- include/vsg/maths/vec3.h | 18 +++++++++--------- include/vsg/maths/vec4.h | 18 +++++++++--------- src/vsg/app/RecordTraversal.cpp | 2 +- src/vsg/app/ViewMatrix.cpp | 4 ++-- src/vsg/utils/Intersector.cpp | 2 +- 12 files changed, 48 insertions(+), 50 deletions(-) diff --git a/include/vsg/app/ViewMatrix.h b/include/vsg/app/ViewMatrix.h index 41c41b43a..4bbc022da 100644 --- a/include/vsg/app/ViewMatrix.h +++ b/include/vsg/app/ViewMatrix.h @@ -36,9 +36,9 @@ namespace vsg /// scenes where standrd double precision is insufficient for avoiding visually significant numerical errors. dvec3 origin; - virtual dmat4 transform(const vsg::dvec3& offset={}) const = 0; + virtual dmat4 transform(const vsg::dvec3& offset = {}) const = 0; - virtual dmat4 inverse(const vsg::dvec3& offset={}) const + virtual dmat4 inverse(const vsg::dvec3& offset = {}) const { return vsg::inverse(transform(offset)); } @@ -88,7 +88,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const dvec3& offset={}) const override; + dmat4 transform(const dvec3& offset = {}) const override; void read(Input& input) override; void write(Output& output) const override; @@ -103,7 +103,6 @@ namespace vsg class VSG_DECLSPEC LookDirection : public vsg::Inherit { public: - LookDirection() : position(0.0, 0.0, 0.0), rotation() @@ -124,11 +123,10 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const dvec3& offset={}) const override; + dmat4 transform(const dvec3& offset = {}) const override; }; VSG_type_name(vsg::LookDirection); - /// RelativeViewMatrix is a ViewMatrix that decorates another ViewMatrix and pre-multiplies its transform matrix to give a relative view matrix. class VSG_DECLSPEC RelativeViewMatrix : public Inherit { @@ -140,7 +138,7 @@ namespace vsg } /// returns matrix * viewMatrix->transform() - dmat4 transform(const vsg::dvec3& offset={}) const override; + dmat4 transform(const vsg::dvec3& offset = {}) const override; dmat4 matrix; ref_ptr viewMatrix; @@ -163,8 +161,8 @@ namespace vsg objectPath(path.begin(), path.end()) {} /// returns matrix * computeTransfrom(objectPath) - dmat4 transform(const vsg::dvec3& offset={}) const override; - dmat4 inverse(const vsg::dvec3& offset={}) const override; + dmat4 transform(const vsg::dvec3& offset = {}) const override; + dmat4 inverse(const vsg::dvec3& offset = {}) const override; dmat4 matrix; RefObjectPath objectPath; diff --git a/include/vsg/core/Array3D.h b/include/vsg/core/Array3D.h index 953446d2a..bc5ddb732 100644 --- a/include/vsg/core/Array3D.h +++ b/include/vsg/core/Array3D.h @@ -396,11 +396,11 @@ namespace vsg VSG_array3D(svec2Array3D, svec2); VSG_array3D(svec3Array3D, svec3); VSG_array3D(svec4Array3D, svec4); - + VSG_array3D(usvec2Array3D, usvec2); VSG_array3D(usvec3Array3D, usvec3); VSG_array3D(usvec4Array3D, usvec4); - + VSG_array3D(ubvec2Array3D, ubvec2); VSG_array3D(ubvec3Array3D, ubvec3); VSG_array3D(ubvec4Array3D, ubvec4); diff --git a/include/vsg/maths/box.h b/include/vsg/maths/box.h index 538ab72ae..80ab988d0 100644 --- a/include/vsg/maths/box.h +++ b/include/vsg/maths/box.h @@ -88,8 +88,8 @@ namespace vsg } }; - using box = t_box; /// float box class - using dbox = t_box; /// double box class + using box = t_box; /// float box class + using dbox = t_box; /// double box class using ldbox = t_box; /// double box class VSG_type_name(vsg::box); diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index ef3b1410a..ee8d9a870 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -119,8 +119,8 @@ namespace vsg const T* data() const { return value[0].data(); } }; - using mat4 = t_mat4; /// float 4x4 matrix - using dmat4 = t_mat4; /// double 4x4 matrix + using mat4 = t_mat4; /// float 4x4 matrix + using dmat4 = t_mat4; /// double 4x4 matrix using ldmat4 = t_mat4; /// long double 4x4 matrix VSG_type_name(vsg::mat4); diff --git a/include/vsg/maths/quat.h b/include/vsg/maths/quat.h index 5d831e19f..726097b3d 100644 --- a/include/vsg/maths/quat.h +++ b/include/vsg/maths/quat.h @@ -145,8 +145,8 @@ namespace vsg explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } }; - using quat = t_quat; /// float quaternion - using dquat = t_quat; /// double quaternion + using quat = t_quat; /// float quaternion + using dquat = t_quat; /// double quaternion using ldquat = t_quat; /// long double quaternion VSG_type_name(vsg::quat); diff --git a/include/vsg/maths/sphere.h b/include/vsg/maths/sphere.h index 23714aec3..587972d6b 100644 --- a/include/vsg/maths/sphere.h +++ b/include/vsg/maths/sphere.h @@ -120,8 +120,8 @@ namespace vsg } }; - using sphere = t_sphere; /// float sphere class - using dsphere = t_sphere; /// double sphere class + using sphere = t_sphere; /// float sphere class + using dsphere = t_sphere; /// double sphere class using ldsphere = t_sphere; /// long double sphere class VSG_type_name(vsg::sphere); diff --git a/include/vsg/maths/vec2.h b/include/vsg/maths/vec2.h index 1f789641f..899ed2bd4 100644 --- a/include/vsg/maths/vec2.h +++ b/include/vsg/maths/vec2.h @@ -136,15 +136,15 @@ namespace vsg explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0; } }; - using vec2 = t_vec2; // float 2D vector - using dvec2 = t_vec2; // double 2D vector - using ldvec2 = t_vec2; // long double 2D vector - using bvec2 = t_vec2; // signed 8 bit integer 2D vector - using svec2 = t_vec2; // signed 16 bit integer 2D vector - using ivec2 = t_vec2; // signed 32 bit integer 2D vector - using ubvec2 = t_vec2; // unsigned 8 bit integer 2D vector - using usvec2 = t_vec2; // unsigned 16 bit integer 2D vector - using uivec2 = t_vec2; // unsigned 32 bit integer 2D vector + using vec2 = t_vec2; // float 2D vector + using dvec2 = t_vec2; // double 2D vector + using ldvec2 = t_vec2; // long double 2D vector + using bvec2 = t_vec2; // signed 8 bit integer 2D vector + using svec2 = t_vec2; // signed 16 bit integer 2D vector + using ivec2 = t_vec2; // signed 32 bit integer 2D vector + using ubvec2 = t_vec2; // unsigned 8 bit integer 2D vector + using usvec2 = t_vec2; // unsigned 16 bit integer 2D vector + using uivec2 = t_vec2; // unsigned 32 bit integer 2D vector VSG_type_name(vsg::vec2); VSG_type_name(vsg::dvec2); diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index 3d927f91f..bccf6962e 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -144,15 +144,15 @@ namespace vsg explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0; } }; - using vec3 = t_vec3; // float 3D vector - using dvec3 = t_vec3; // double 3D vector - using ldvec3 = t_vec3; // long double 3D vector - using bvec3 = t_vec3; // signed 8 bit integer 3D vector - using svec3 = t_vec3; // signed 16 bit integer 3D vector - using ivec3 = t_vec3; // signed 32 bit integer 3D vector - using ubvec3 = t_vec3; // unsigned 8 bit integer 3D vector - using usvec3 = t_vec3; // unsigned 16 bit integer 3D vector - using uivec3 = t_vec3; // unsigned 32 bit integer 3D vector + using vec3 = t_vec3; // float 3D vector + using dvec3 = t_vec3; // double 3D vector + using ldvec3 = t_vec3; // long double 3D vector + using bvec3 = t_vec3; // signed 8 bit integer 3D vector + using svec3 = t_vec3; // signed 16 bit integer 3D vector + using ivec3 = t_vec3; // signed 32 bit integer 3D vector + using ubvec3 = t_vec3; // unsigned 8 bit integer 3D vector + using usvec3 = t_vec3; // unsigned 16 bit integer 3D vector + using uivec3 = t_vec3; // unsigned 32 bit integer 3D vector VSG_type_name(vsg::vec3); VSG_type_name(vsg::dvec3); diff --git a/include/vsg/maths/vec4.h b/include/vsg/maths/vec4.h index 149c3009c..4ed3eb08c 100644 --- a/include/vsg/maths/vec4.h +++ b/include/vsg/maths/vec4.h @@ -174,15 +174,15 @@ namespace vsg explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } }; - using vec4 = t_vec4; // float 4D vector - using dvec4 = t_vec4; // double 4D vector - using ldvec4 = t_vec4; // long double 4D vector - using bvec4 = t_vec4; // signed 8 bit integer 4D vector - using svec4 = t_vec4; // signed 16 bit integer 4D vector - using ivec4 = t_vec4; // signed 32 bit integer 4D vector - using ubvec4 = t_vec4; // unsigned 8 bit integer 4D vector - using usvec4 = t_vec4; // unsigned 16 bit integer 4D vector - using uivec4 = t_vec4; // unsigned 32 bit integer 4D vector + using vec4 = t_vec4; // float 4D vector + using dvec4 = t_vec4; // double 4D vector + using ldvec4 = t_vec4; // long double 4D vector + using bvec4 = t_vec4; // signed 8 bit integer 4D vector + using svec4 = t_vec4; // signed 16 bit integer 4D vector + using ivec4 = t_vec4; // signed 32 bit integer 4D vector + using ubvec4 = t_vec4; // unsigned 8 bit integer 4D vector + using usvec4 = t_vec4; // unsigned 16 bit integer 4D vector + using uivec4 = t_vec4; // unsigned 32 bit integer 4D vector VSG_type_name(vsg::vec4); VSG_type_name(vsg::dvec4); diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index b084978ac..1c06fc9ed 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -27,6 +27,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include @@ -35,7 +36,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include #include #include #include diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 8c77d74d4..7f2fa6ee9 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -62,7 +62,7 @@ void LookDirection::set(const dmat4& matrix) dmat4 LookDirection::transform(const dvec3& offset) const { - return vsg::rotate(-rotation) * vsg::translate(offset-origin-position); + return vsg::rotate(-rotation) * vsg::translate(offset - origin - position); } dmat4 RelativeViewMatrix::transform(const dvec3& offset) const @@ -72,7 +72,7 @@ dmat4 RelativeViewMatrix::transform(const dvec3& offset) const dmat4 TrackingViewMatrix::transform(const dvec3& offset) const { - return matrix * vsg::translate(offset-origin) * vsg::inverse(computeTransform(objectPath)); + return matrix * vsg::translate(offset - origin) * vsg::inverse(computeTransform(objectPath)); } dmat4 TrackingViewMatrix::inverse(const dvec3& offset) const diff --git a/src/vsg/utils/Intersector.cpp b/src/vsg/utils/Intersector.cpp index 10309aeb2..9de7d9ab3 100644 --- a/src/vsg/utils/Intersector.cpp +++ b/src/vsg/utils/Intersector.cpp @@ -27,9 +27,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include #include #include +#include using namespace vsg; From 2dda950efdbb65e3b1bc486497d3505d579d5b8c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Nov 2024 10:43:34 +0000 Subject: [PATCH 11/26] Added long double support --- include/vsg/app/ViewMatrix.h | 16 ++++++++-------- include/vsg/io/AsciiInput.h | 1 + include/vsg/io/AsciiOutput.h | 6 ++++++ include/vsg/io/BinaryInput.h | 1 + include/vsg/io/BinaryOutput.h | 1 + include/vsg/io/Input.h | 4 ++++ include/vsg/io/Output.h | 4 ++++ include/vsg/nodes/CoordinateFrame.h | 2 +- src/vsg/app/ViewMatrix.cpp | 18 +++++++++--------- src/vsg/nodes/CoordinateFrame.cpp | 2 +- 10 files changed, 36 insertions(+), 19 deletions(-) diff --git a/include/vsg/app/ViewMatrix.h b/include/vsg/app/ViewMatrix.h index 4bbc022da..6ad22af99 100644 --- a/include/vsg/app/ViewMatrix.h +++ b/include/vsg/app/ViewMatrix.h @@ -34,11 +34,11 @@ namespace vsg /// origin value provides a means of translating the view matrix relative to the origin of any CoordinateFrame subgraphs /// to maximize the precision when moving around the CoordinateFrame subgraph. This is helpful for astronmically large /// scenes where standrd double precision is insufficient for avoiding visually significant numerical errors. - dvec3 origin; + ldvec3 origin; - virtual dmat4 transform(const vsg::dvec3& offset = {}) const = 0; + virtual dmat4 transform(const vsg::ldvec3& offset = {}) const = 0; - virtual dmat4 inverse(const vsg::dvec3& offset = {}) const + virtual dmat4 inverse(const vsg::ldvec3& offset = {}) const { return vsg::inverse(transform(offset)); } @@ -88,7 +88,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const dvec3& offset = {}) const override; + dmat4 transform(const ldvec3& offset = {}) const override; void read(Input& input) override; void write(Output& output) const override; @@ -123,7 +123,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const dvec3& offset = {}) const override; + dmat4 transform(const ldvec3& offset = {}) const override; }; VSG_type_name(vsg::LookDirection); @@ -138,7 +138,7 @@ namespace vsg } /// returns matrix * viewMatrix->transform() - dmat4 transform(const vsg::dvec3& offset = {}) const override; + dmat4 transform(const ldvec3& offset = {}) const override; dmat4 matrix; ref_ptr viewMatrix; @@ -161,8 +161,8 @@ namespace vsg objectPath(path.begin(), path.end()) {} /// returns matrix * computeTransfrom(objectPath) - dmat4 transform(const vsg::dvec3& offset = {}) const override; - dmat4 inverse(const vsg::dvec3& offset = {}) const override; + dmat4 transform(const ldvec3& offset = {}) const override; + dmat4 inverse(const ldvec3& offset = {}) const override; dmat4 matrix; RefObjectPath objectPath; diff --git a/include/vsg/io/AsciiInput.h b/include/vsg/io/AsciiInput.h index 3783c496e..e83cecb44 100644 --- a/include/vsg/io/AsciiInput.h +++ b/include/vsg/io/AsciiInput.h @@ -85,6 +85,7 @@ namespace vsg void read(size_t num, uint64_t* value) override { _read(num, value); } void read(size_t num, float* value) override { _read(num, value); } void read(size_t num, double* value) override { _read(num, value); } + void read(size_t num, long double* value) override { _read(num, value); } // read in an individual string void _read(std::string& value); diff --git a/include/vsg/io/AsciiOutput.h b/include/vsg/io/AsciiOutput.h index ddb146724..5eabb5591 100644 --- a/include/vsg/io/AsciiOutput.h +++ b/include/vsg/io/AsciiOutput.h @@ -136,6 +136,11 @@ namespace vsg _output.precision(double_precision); _write_real(num, value); } + void write(size_t num, const long double* value) override + { + _output.precision(long_double_precision); + _write_real(num, value); + } void _write(const std::string& str) { @@ -161,6 +166,7 @@ namespace vsg int float_precision = 6; int double_precision = 12; + int long_double_precision = 24; protected: std::ostream& _output; diff --git a/include/vsg/io/BinaryInput.h b/include/vsg/io/BinaryInput.h index 9e2ac124e..1ccd1f887 100644 --- a/include/vsg/io/BinaryInput.h +++ b/include/vsg/io/BinaryInput.h @@ -55,6 +55,7 @@ namespace vsg void read(size_t num, uint64_t* value) override { _read(num, value); } void read(size_t num, float* value) override { _read(num, value); } void read(size_t num, double* value) override { _read(num, value); } + void read(size_t num, long double* value) override { _read(num, value); } // read in an individual string void _read(std::string& value); diff --git a/include/vsg/io/BinaryOutput.h b/include/vsg/io/BinaryOutput.h index bddc380d9..97a2befb3 100644 --- a/include/vsg/io/BinaryOutput.h +++ b/include/vsg/io/BinaryOutput.h @@ -50,6 +50,7 @@ namespace vsg void write(size_t num, const uint64_t* value) override { _write(num, value); } void write(size_t num, const float* value) override { _write(num, value); } void write(size_t num, const double* value) override { _write(num, value); } + void write(size_t num, const long double* value) override { _write(num, value); } void _write(const std::string& str); void _write(const std::wstring& str); diff --git a/include/vsg/io/Input.h b/include/vsg/io/Input.h index cdc5f303f..0bded3bbc 100644 --- a/include/vsg/io/Input.h +++ b/include/vsg/io/Input.h @@ -61,6 +61,7 @@ namespace vsg virtual void read(size_t num, uint64_t* value) = 0; virtual void read(size_t num, float* value) = 0; virtual void read(size_t num, double* value) = 0; + virtual void read(size_t num, long double* value) = 0; virtual void read(size_t num, std::string* value) = 0; virtual void read(size_t num, std::wstring* value) = 0; virtual void read(size_t num, Path* value) = 0; @@ -78,6 +79,9 @@ namespace vsg void read(size_t num, vec4* value) { read(num * value->size(), value->data()); } void read(size_t num, dvec2* value) { read(num * value->size(), value->data()); } void read(size_t num, dvec3* value) { read(num * value->size(), value->data()); } + void read(size_t num, ldvec4* value) { read(num * value->size(), value->data()); } + void read(size_t num, ldvec2* value) { read(num * value->size(), value->data()); } + void read(size_t num, ldvec3* value) { read(num * value->size(), value->data()); } void read(size_t num, dvec4* value) { read(num * value->size(), value->data()); } void read(size_t num, bvec2* value) { read(num * value->size(), value->data()); } void read(size_t num, bvec3* value) { read(num * value->size(), value->data()); } diff --git a/include/vsg/io/Output.h b/include/vsg/io/Output.h index ebe89f3a7..216b1aabb 100644 --- a/include/vsg/io/Output.h +++ b/include/vsg/io/Output.h @@ -61,6 +61,7 @@ namespace vsg virtual void write(size_t num, const uint64_t* value) = 0; virtual void write(size_t num, const float* value) = 0; virtual void write(size_t num, const double* value) = 0; + virtual void write(size_t num, const long double* value) = 0; virtual void write(size_t num, const std::string* value) = 0; virtual void write(size_t num, const std::wstring* value) = 0; virtual void write(size_t num, const Path* value) = 0; @@ -79,6 +80,9 @@ namespace vsg void write(size_t num, const dvec2* value) { write(num * value->size(), value->data()); } void write(size_t num, const dvec3* value) { write(num * value->size(), value->data()); } void write(size_t num, const dvec4* value) { write(num * value->size(), value->data()); } + void write(size_t num, const ldvec2* value) { write(num * value->size(), value->data()); } + void write(size_t num, const ldvec3* value) { write(num * value->size(), value->data()); } + void write(size_t num, const ldvec4* value) { write(num * value->size(), value->data()); } void write(size_t num, const bvec2* value) { write(num * value->size(), value->data()); } void write(size_t num, const bvec3* value) { write(num * value->size(), value->data()); } void write(size_t num, const bvec4* value) { write(num * value->size(), value->data()); } diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 36fef0cec..e30c9a2df 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -25,7 +25,7 @@ namespace vsg CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop = {}); std::string name; - dvec3 origin; + ldvec3 origin; dmat4 transform(const dmat4& mv) const override; diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 7f2fa6ee9..921f29221 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -48,9 +48,9 @@ void LookAt::set(const dmat4& matrix) eye = matrix * dvec3(0.0, 0.0, 0.0); } -dmat4 LookAt::transform(const dvec3& offset) const +dmat4 LookAt::transform(const ldvec3& offset) const { - dvec3 delta = origin - offset; + dvec3 delta = dvec3(origin - offset); return vsg::lookAt(eye + delta, center + delta, up); } @@ -60,22 +60,22 @@ void LookDirection::set(const dmat4& matrix) vsg::decompose(matrix, position, rotation, scale); } -dmat4 LookDirection::transform(const dvec3& offset) const +dmat4 LookDirection::transform(const ldvec3& offset) const { - return vsg::rotate(-rotation) * vsg::translate(offset - origin - position); + return vsg::rotate(-rotation) * vsg::translate(dvec3(origin - offset) - position); } -dmat4 RelativeViewMatrix::transform(const dvec3& offset) const +dmat4 RelativeViewMatrix::transform(const ldvec3& offset) const { return matrix * viewMatrix->transform(offset); } -dmat4 TrackingViewMatrix::transform(const dvec3& offset) const +dmat4 TrackingViewMatrix::transform(const ldvec3& offset) const { - return matrix * vsg::translate(offset - origin) * vsg::inverse(computeTransform(objectPath)); + return matrix * vsg::translate(dvec3(origin - offset)) * vsg::inverse(computeTransform(objectPath)); } -dmat4 TrackingViewMatrix::inverse(const dvec3& offset) const +dmat4 TrackingViewMatrix::inverse(const ldvec3& offset) const { - return vsg::computeTransform(objectPath) * vsg::translate(origin - offset) * vsg::inverse(matrix); + return vsg::computeTransform(objectPath) * vsg::translate(dvec3(origin - offset)) * vsg::inverse(matrix); } diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 7c7f6669a..0a996b0ab 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -58,5 +58,5 @@ void CoordinateFrame::write(Output& output) const dmat4 CoordinateFrame::transform(const dmat4& mv) const { - return mv * translate(origin); + return mv * translate(dvec3(origin)); } From 81155516786f8f7dc1b5118bc121df8dc60651b3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Nov 2024 11:26:48 +0000 Subject: [PATCH 12/26] Added initializer to solve issue wiht long double initializers. --- include/vsg/maths/vec3.h | 2 +- src/vsg/app/ViewMatrix.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index bccf6962e..27d27a7ef 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -52,7 +52,7 @@ namespace vsg }; constexpr t_vec3() : - value{} {} + value{0, 0, 0} {} constexpr t_vec3(const t_vec3& v) : value{v.x, v.y, v.z} {} constexpr t_vec3& operator=(const t_vec3&) = default; diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 921f29221..9f80d55fb 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -62,7 +62,7 @@ void LookDirection::set(const dmat4& matrix) dmat4 LookDirection::transform(const ldvec3& offset) const { - return vsg::rotate(-rotation) * vsg::translate(dvec3(origin - offset) - position); + return vsg::rotate(-rotation) * vsg::translate(dvec3(offset - origin) - position); } dmat4 RelativeViewMatrix::transform(const ldvec3& offset) const @@ -72,10 +72,10 @@ dmat4 RelativeViewMatrix::transform(const ldvec3& offset) const dmat4 TrackingViewMatrix::transform(const ldvec3& offset) const { - return matrix * vsg::translate(dvec3(origin - offset)) * vsg::inverse(computeTransform(objectPath)); + return matrix * vsg::translate(dvec3(offset - origin)) * vsg::inverse(computeTransform(objectPath)); } dmat4 TrackingViewMatrix::inverse(const ldvec3& offset) const { - return vsg::computeTransform(objectPath) * vsg::translate(dvec3(origin - offset)) * vsg::inverse(matrix); + return vsg::computeTransform(objectPath) * vsg::translate(dvec3(offset - origin)) * vsg::inverse(matrix); } From aba69e149baf955135c0ef1a03c6890305ca7f79 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 22 Nov 2024 15:45:08 +0000 Subject: [PATCH 13/26] Changed CoordinateFrame::orign and ViewMatrix::origin back to dvec3 to avoid odd crash when writing to ViewMatrix instances. --- include/vsg/app/ViewMatrix.h | 19 +++++++++++-------- include/vsg/nodes/CoordinateFrame.h | 2 +- src/vsg/app/ViewMatrix.cpp | 24 +++++++++++++++++++----- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/vsg/app/ViewMatrix.h b/include/vsg/app/ViewMatrix.h index 6ad22af99..7d974e128 100644 --- a/include/vsg/app/ViewMatrix.h +++ b/include/vsg/app/ViewMatrix.h @@ -34,14 +34,17 @@ namespace vsg /// origin value provides a means of translating the view matrix relative to the origin of any CoordinateFrame subgraphs /// to maximize the precision when moving around the CoordinateFrame subgraph. This is helpful for astronmically large /// scenes where standrd double precision is insufficient for avoiding visually significant numerical errors. - ldvec3 origin; + dvec3 origin; - virtual dmat4 transform(const vsg::ldvec3& offset = {}) const = 0; + virtual dmat4 transform(const dvec3& offset = {}) const = 0; - virtual dmat4 inverse(const vsg::ldvec3& offset = {}) const + virtual dmat4 inverse(const dvec3& offset = {}) const { return vsg::inverse(transform(offset)); } + + void read(Input& input) override; + void write(Output& output) const override; }; VSG_type_name(vsg::ViewMatrix); @@ -88,7 +91,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const ldvec3& offset = {}) const override; + dmat4 transform(const dvec3& offset = {}) const override; void read(Input& input) override; void write(Output& output) const override; @@ -123,7 +126,7 @@ namespace vsg void set(const dmat4& matrix); - dmat4 transform(const ldvec3& offset = {}) const override; + dmat4 transform(const dvec3& offset = {}) const override; }; VSG_type_name(vsg::LookDirection); @@ -138,7 +141,7 @@ namespace vsg } /// returns matrix * viewMatrix->transform() - dmat4 transform(const ldvec3& offset = {}) const override; + dmat4 transform(const dvec3& offset = {}) const override; dmat4 matrix; ref_ptr viewMatrix; @@ -161,8 +164,8 @@ namespace vsg objectPath(path.begin(), path.end()) {} /// returns matrix * computeTransfrom(objectPath) - dmat4 transform(const ldvec3& offset = {}) const override; - dmat4 inverse(const ldvec3& offset = {}) const override; + dmat4 transform(const dvec3& offset = {}) const override; + dmat4 inverse(const dvec3& offset = {}) const override; dmat4 matrix; RefObjectPath objectPath; diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index e30c9a2df..36fef0cec 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -25,7 +25,7 @@ namespace vsg CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop = {}); std::string name; - ldvec3 origin; + dvec3 origin; dmat4 transform(const dmat4& mv) const override; diff --git a/src/vsg/app/ViewMatrix.cpp b/src/vsg/app/ViewMatrix.cpp index 9f80d55fb..e5d2548c2 100644 --- a/src/vsg/app/ViewMatrix.cpp +++ b/src/vsg/app/ViewMatrix.cpp @@ -16,6 +16,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; +void ViewMatrix::read(Input& input) +{ + Object::read(input); + + input.read("origin", origin); +} + +void ViewMatrix::write(Output& output) const +{ + Object::write(output); + + output.write("origin", origin); +} + void LookAt::read(Input& input) { ViewMatrix::read(input); @@ -48,7 +62,7 @@ void LookAt::set(const dmat4& matrix) eye = matrix * dvec3(0.0, 0.0, 0.0); } -dmat4 LookAt::transform(const ldvec3& offset) const +dmat4 LookAt::transform(const dvec3& offset) const { dvec3 delta = dvec3(origin - offset); return vsg::lookAt(eye + delta, center + delta, up); @@ -60,22 +74,22 @@ void LookDirection::set(const dmat4& matrix) vsg::decompose(matrix, position, rotation, scale); } -dmat4 LookDirection::transform(const ldvec3& offset) const +dmat4 LookDirection::transform(const dvec3& offset) const { return vsg::rotate(-rotation) * vsg::translate(dvec3(offset - origin) - position); } -dmat4 RelativeViewMatrix::transform(const ldvec3& offset) const +dmat4 RelativeViewMatrix::transform(const dvec3& offset) const { return matrix * viewMatrix->transform(offset); } -dmat4 TrackingViewMatrix::transform(const ldvec3& offset) const +dmat4 TrackingViewMatrix::transform(const dvec3& offset) const { return matrix * vsg::translate(dvec3(offset - origin)) * vsg::inverse(computeTransform(objectPath)); } -dmat4 TrackingViewMatrix::inverse(const ldvec3& offset) const +dmat4 TrackingViewMatrix::inverse(const dvec3& offset) const { return vsg::computeTransform(objectPath) * vsg::translate(dvec3(offset - origin)) * vsg::inverse(matrix); } From a3ed880eff5a18224c55b51d4c75d9cadaf3c8cb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 23 Nov 2024 13:14:17 +0000 Subject: [PATCH 14/26] Added rotation to CoordinateFrame. --- include/vsg/nodes/CoordinateFrame.h | 1 + src/vsg/app/RecordTraversal.cpp | 2 +- src/vsg/nodes/CoordinateFrame.cpp | 10 +++++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 36fef0cec..29a996eb8 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -26,6 +26,7 @@ namespace vsg std::string name; dvec3 origin; + dquat rotation; dmat4 transform(const dmat4& mv) const override; diff --git a/src/vsg/app/RecordTraversal.cpp b/src/vsg/app/RecordTraversal.cpp index 1c06fc9ed..2ecf91a5a 100644 --- a/src/vsg/app/RecordTraversal.cpp +++ b/src/vsg/app/RecordTraversal.cpp @@ -446,7 +446,7 @@ void RecordTraversal::apply(const CoordinateFrame& cf) if (viewMatrix) { - _state->modelviewMatrixStack.push(viewMatrix->transform(cf.origin)); + _state->modelviewMatrixStack.push(viewMatrix->transform(cf.origin) * vsg::rotate(cf.rotation)); } else { diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 0a996b0ab..d8bee299c 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -24,7 +24,8 @@ CoordinateFrame::CoordinateFrame() CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyop) : Inherit(rhs, copyop), name(rhs.name), - origin(rhs.origin) + origin(rhs.origin), + rotation(rhs.rotation) { } @@ -35,7 +36,8 @@ int CoordinateFrame::compare(const Object& rhs_object) const const auto& rhs = static_cast(rhs_object); if ((result = compare_value(name, rhs.name)) != 0) return result; - return compare_value(origin, rhs.origin); + if ((result = compare_value(origin, rhs.origin)) != 0) return result; + return compare_value(rotation, rhs.rotation); } void CoordinateFrame::read(Input& input) @@ -43,6 +45,7 @@ void CoordinateFrame::read(Input& input) Node::read(input); input.read("name", name); input.read("origin", origin); + input.read("rotation", rotation); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -52,11 +55,12 @@ void CoordinateFrame::write(Output& output) const Node::write(output); output.write("name", name); output.write("origin", origin); + output.write("rotation", rotation); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } dmat4 CoordinateFrame::transform(const dmat4& mv) const { - return mv * translate(dvec3(origin)); + return mv * translate(dvec3(origin)) * rotate(rotation); } From f0fba03fe0220b347084800e560e7289e04c972b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Nov 2024 17:15:30 +0000 Subject: [PATCH 15/26] Preliminary support for handling different long double implementations on different platforms. --- include/vsg/io/BinaryInput.h | 2 +- include/vsg/io/BinaryOutput.h | 2 +- include/vsg/maths/common.h | 4 ++++ src/vsg/CMakeLists.txt | 1 + src/vsg/core/Version.cpp | 1 + src/vsg/io/BinaryInput.cpp | 25 +++++++++++++++++++++++++ src/vsg/io/BinaryOutput.cpp | 7 +++++++ src/vsg/maths/common.cpp | 26 ++++++++++++++++++++++++++ 8 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 src/vsg/maths/common.cpp diff --git a/include/vsg/io/BinaryInput.h b/include/vsg/io/BinaryInput.h index 1ccd1f887..600442f87 100644 --- a/include/vsg/io/BinaryInput.h +++ b/include/vsg/io/BinaryInput.h @@ -55,7 +55,7 @@ namespace vsg void read(size_t num, uint64_t* value) override { _read(num, value); } void read(size_t num, float* value) override { _read(num, value); } void read(size_t num, double* value) override { _read(num, value); } - void read(size_t num, long double* value) override { _read(num, value); } + void read(size_t num, long double* value) override; // read in an individual string void _read(std::string& value); diff --git a/include/vsg/io/BinaryOutput.h b/include/vsg/io/BinaryOutput.h index 97a2befb3..63124a4af 100644 --- a/include/vsg/io/BinaryOutput.h +++ b/include/vsg/io/BinaryOutput.h @@ -50,7 +50,7 @@ namespace vsg void write(size_t num, const uint64_t* value) override { _write(num, value); } void write(size_t num, const float* value) override { _write(num, value); } void write(size_t num, const double* value) override { _write(num, value); } - void write(size_t num, const long double* value) override { _write(num, value); } + void write(size_t num, const long double* value) override; void _write(const std::string& str); void _write(const std::wstring& str); diff --git a/include/vsg/maths/common.h b/include/vsg/maths/common.h index 97efdca31..dcd617ecf 100644 --- a/include/vsg/maths/common.h +++ b/include/vsg/maths/common.h @@ -69,4 +69,8 @@ namespace vsg return start * one_minus_r + end * r; } + /// return the number of bits supported by the long double implementation - VisualStudio by default 64 bits, stored as 8 bytes, & Linux x86_64 defaults to 80 bits stored as 16bytes, some CPU achitectures support full 128 bits/16 bytes. + extern VSG_DECLSPEC uint32_t native_long_double_bits(); + + } // namespace vsg diff --git a/src/vsg/CMakeLists.txt b/src/vsg/CMakeLists.txt index 0ddb87a7c..dffbe08be 100644 --- a/src/vsg/CMakeLists.txt +++ b/src/vsg/CMakeLists.txt @@ -22,6 +22,7 @@ set(SOURCES core/Visitor.cpp core/Version.cpp + maths/common.cpp maths/maths_transform.cpp nodes/Group.cpp diff --git a/src/vsg/core/Version.cpp b/src/vsg/core/Version.cpp index 7eac7bc00..a29825625 100644 --- a/src/vsg/core/Version.cpp +++ b/src/vsg/core/Version.cpp @@ -43,4 +43,5 @@ extern "C" return 0; #endif } + } diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index f67e21c2b..f35454d2e 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -88,6 +88,31 @@ void BinaryInput::read(size_t num, Path* value) } } +void BinaryInput::read(size_t num, long double* value) +{ + uint32_t native_type = native_long_double_bits(); + + uint32_t read_type; + _read(1, &read_type); + + if (read_type == native_type) + { + info("reading native long double without conversion."); + _read(num, value); + } + else + { + info("reading long double requiring conversion from ", read_type, " to ", native_type); + + // 64 to 80 + // 64 to 128 + // 80 to 64 + // 80 to 128 + // 128 to 64 + // 128 to 64 + } +} + vsg::ref_ptr BinaryInput::read() { ObjectID id = objectID(); diff --git a/src/vsg/io/BinaryOutput.cpp b/src/vsg/io/BinaryOutput.cpp index 36c3aa80a..03f2e4cae 100644 --- a/src/vsg/io/BinaryOutput.cpp +++ b/src/vsg/io/BinaryOutput.cpp @@ -81,6 +81,13 @@ void BinaryOutput::write(size_t num, const Path* value) } } +void BinaryOutput::write(size_t num, const long double* value) +{ + uint32_t write_type = native_long_double_bits(); + _write(1, &write_type); + _write(num, value); +} + void BinaryOutput::write(const vsg::Object* object) { if (auto itr = objectIDMap.find(object); itr != objectIDMap.end()) diff --git a/src/vsg/maths/common.cpp b/src/vsg/maths/common.cpp new file mode 100644 index 000000000..bd47a48f0 --- /dev/null +++ b/src/vsg/maths/common.cpp @@ -0,0 +1,26 @@ + +/* + +Copyright(c) 2024 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include + +uint32_t vsg::native_long_double_bits() +{ +#if defined(_MSC_VER) + return 64; +#elif defined(__GNUC__) || defined(__clang__) + if (typeid(long double)==typeid(__float80)) return 80; + if (typeid(long double)==typeid(__float128)) return 128; + if (typeid(long double)==typeid(double)) return 64; +#endif + return (sizeof(long double)==8) ? 64 : 128; +} From 95bec47ffb7037468588fe24695503e2572fc9cc Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Nov 2024 17:44:47 +0000 Subject: [PATCH 16/26] Rewrote the test for long double bits to avoid platform specific code. --- src/vsg/maths/common.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/vsg/maths/common.cpp b/src/vsg/maths/common.cpp index bd47a48f0..d7f878bb4 100644 --- a/src/vsg/maths/common.cpp +++ b/src/vsg/maths/common.cpp @@ -13,14 +13,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include +#include + uint32_t vsg::native_long_double_bits() { -#if defined(_MSC_VER) - return 64; -#elif defined(__GNUC__) || defined(__clang__) - if (typeid(long double)==typeid(__float80)) return 80; - if (typeid(long double)==typeid(__float128)) return 128; - if (typeid(long double)==typeid(double)) return 64; -#endif - return (sizeof(long double)==8) ? 64 : 128; + if (LDBL_MANT_DIG == DBL_MANT_DIG) return 64; + return LDBL_MANT_DIG <= 64 ? 80 : 128; } From 92f21f481cc3f862692956c684f397ccf35dd816 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Nov 2024 18:11:31 +0000 Subject: [PATCH 17/26] VS build fix --- include/vsg/nodes/CoordinateFrame.h | 2 ++ src/vsg/maths/common.cpp | 1 + src/vsg/nodes/CoordinateFrame.cpp | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 29a996eb8..af6ea16af 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -28,6 +28,8 @@ namespace vsg dvec3 origin; dquat rotation; + ldvec3 temp_ldvec3; + dmat4 transform(const dmat4& mv) const override; public: diff --git a/src/vsg/maths/common.cpp b/src/vsg/maths/common.cpp index d7f878bb4..87f3575d6 100644 --- a/src/vsg/maths/common.cpp +++ b/src/vsg/maths/common.cpp @@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #include +#include #include diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index d8bee299c..5505fe7cc 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -25,7 +25,8 @@ CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyo Inherit(rhs, copyop), name(rhs.name), origin(rhs.origin), - rotation(rhs.rotation) + rotation(rhs.rotation), + temp_ldvec3(rhs.temp_ldvec3) { } @@ -37,6 +38,7 @@ int CoordinateFrame::compare(const Object& rhs_object) const const auto& rhs = static_cast(rhs_object); if ((result = compare_value(name, rhs.name)) != 0) return result; if ((result = compare_value(origin, rhs.origin)) != 0) return result; + if ((result = compare_value(temp_ldvec3, rhs.temp_ldvec3)) != 0) return result; return compare_value(rotation, rhs.rotation); } @@ -46,6 +48,7 @@ void CoordinateFrame::read(Input& input) input.read("name", name); input.read("origin", origin); input.read("rotation", rotation); + input.read("temp_ldvec3" , temp_ldvec3); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -56,6 +59,7 @@ void CoordinateFrame::write(Output& output) const output.write("name", name); output.write("origin", origin); output.write("rotation", rotation); + output.write("temp_ldvec3" , temp_ldvec3); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } From b4127bc0df7dfd4d9ef8501a8a7d05737d5af205 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Nov 2024 18:11:31 +0000 Subject: [PATCH 18/26] VS build fix --- include/vsg/nodes/CoordinateFrame.h | 2 ++ src/vsg/maths/common.cpp | 1 + src/vsg/nodes/CoordinateFrame.cpp | 6 +++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 29a996eb8..af6ea16af 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -28,6 +28,8 @@ namespace vsg dvec3 origin; dquat rotation; + ldvec3 temp_ldvec3; + dmat4 transform(const dmat4& mv) const override; public: diff --git a/src/vsg/maths/common.cpp b/src/vsg/maths/common.cpp index d7f878bb4..87f3575d6 100644 --- a/src/vsg/maths/common.cpp +++ b/src/vsg/maths/common.cpp @@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #include +#include #include diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index d8bee299c..5505fe7cc 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -25,7 +25,8 @@ CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyo Inherit(rhs, copyop), name(rhs.name), origin(rhs.origin), - rotation(rhs.rotation) + rotation(rhs.rotation), + temp_ldvec3(rhs.temp_ldvec3) { } @@ -37,6 +38,7 @@ int CoordinateFrame::compare(const Object& rhs_object) const const auto& rhs = static_cast(rhs_object); if ((result = compare_value(name, rhs.name)) != 0) return result; if ((result = compare_value(origin, rhs.origin)) != 0) return result; + if ((result = compare_value(temp_ldvec3, rhs.temp_ldvec3)) != 0) return result; return compare_value(rotation, rhs.rotation); } @@ -46,6 +48,7 @@ void CoordinateFrame::read(Input& input) input.read("name", name); input.read("origin", origin); input.read("rotation", rotation); + input.read("temp_ldvec3" , temp_ldvec3); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -56,6 +59,7 @@ void CoordinateFrame::write(Output& output) const output.write("name", name); output.write("origin", origin); output.write("rotation", rotation); + output.write("temp_ldvec3" , temp_ldvec3); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } From e075b20386cbe952a2a115e71595a248460d6874 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 11:20:21 +0000 Subject: [PATCH 19/26] Added handling of different long double read and native types. --- src/vsg/io/BinaryInput.cpp | 92 ++++++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index f35454d2e..976283bcd 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -88,6 +88,26 @@ void BinaryInput::read(size_t num, Path* value) } } + +struct double_64 +{ + unsigned int sign : 1; + unsigned int exponent : 11; + unsigned long mantissa : 52; +}; + +struct double_128 +{ + unsigned int sign : 1; + unsigned int exponent : 15; + union + { + unsigned long mantissa_64 : 52; + uint8_t mantissa[14]; + }; +}; + + void BinaryInput::read(size_t num, long double* value) { uint32_t native_type = native_long_double_bits(); @@ -102,14 +122,70 @@ void BinaryInput::read(size_t num, long double* value) } else { - info("reading long double requiring conversion from ", read_type, " to ", native_type); - - // 64 to 80 - // 64 to 128 - // 80 to 64 - // 80 to 128 - // 128 to 64 - // 128 to 64 + + if (read_type == 64) + { + info("reading long double as double then converting conversion from ", read_type, " to ", native_type); + + // 64 to 80 + // 64 to 128 + + std::vector data(num); + _read(num, data.data()); + + for(auto& v : data) + { + *(value++) = v; + } + } + else // (read_type == 80) || read_type ==128 + { + info("reading long double as 80bit then converting conversion from ", read_type, " to ", native_type); + + std::vector data(num); + + _input.read(reinterpret_cast(data.data()), num * sizeof(double_128)); + + if (native_type == 64) + { + double_64* dest = reinterpret_cast(value); + for(auto& v : data) + { + auto& d = *(dest++); + d.sign = v.sign; + d.exponent = v.exponent; + d.mantissa = v.mantissa_64; + } + } + else if (native_type == 80) + { + double_128* dest = reinterpret_cast(value); + for(auto& v : data) + { + auto& d = *(dest++); + d.sign = v.sign; + d.exponent = v.exponent; + + // copy fraction and fill in zeros at end + for(int i=0; i<8; ++i) d.mantissa[i] = v.mantissa[i]; + } + } + else if (native_type == 128) + { + double_128* dest = reinterpret_cast(value); + for(auto& v : data) + { + auto& d = *(dest++); + d.sign = v.sign; + d.exponent = v.exponent; + + // copy fraction and fill in zeros at end + int i=0; + for(; i<8; ++i) d.mantissa[i] = v.mantissa[i]; + for(; i<14; ++i) d.mantissa[i] = 0; + } + } + } } } From 8f24b89346f7bf2038de2a80298c9d41dc255547 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 11:42:42 +0000 Subject: [PATCH 20/26] Tightened up types for VS build. --- src/vsg/io/BinaryInput.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index 976283bcd..2f7c754ea 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -91,18 +91,18 @@ void BinaryInput::read(size_t num, Path* value) struct double_64 { - unsigned int sign : 1; - unsigned int exponent : 11; - unsigned long mantissa : 52; + uint8_t sign : 1; + uint16_t exponent : 11; + uint64_t mantissa : 52; }; struct double_128 { - unsigned int sign : 1; - unsigned int exponent : 15; + uint8_t sign : 1; + uint16_t exponent : 15; union { - unsigned long mantissa_64 : 52; + uint64_t mantissa_64 : 52; uint8_t mantissa[14]; }; }; From 6187b388ed9eb33193829432c9f2f888b3df3dfa Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 14:15:56 +0000 Subject: [PATCH 21/26] Removed debug output --- src/vsg/io/BinaryInput.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index 2f7c754ea..b350f6648 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -122,14 +122,10 @@ void BinaryInput::read(size_t num, long double* value) } else { - if (read_type == 64) { - info("reading long double as double then converting conversion from ", read_type, " to ", native_type); - // 64 to 80 // 64 to 128 - std::vector data(num); _read(num, data.data()); @@ -140,8 +136,6 @@ void BinaryInput::read(size_t num, long double* value) } else // (read_type == 80) || read_type ==128 { - info("reading long double as 80bit then converting conversion from ", read_type, " to ", native_type); - std::vector data(num); _input.read(reinterpret_cast(data.data()), num * sizeof(double_128)); From d9e73c2418880ab2c5839f9c24fb0621d4d3b80c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 14:18:54 +0000 Subject: [PATCH 22/26] Removed temporary ldvec3 test member. --- include/vsg/nodes/CoordinateFrame.h | 2 -- src/vsg/nodes/CoordinateFrame.cpp | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index af6ea16af..29a996eb8 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -28,8 +28,6 @@ namespace vsg dvec3 origin; dquat rotation; - ldvec3 temp_ldvec3; - dmat4 transform(const dmat4& mv) const override; public: diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 5505fe7cc..d8bee299c 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -25,8 +25,7 @@ CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyo Inherit(rhs, copyop), name(rhs.name), origin(rhs.origin), - rotation(rhs.rotation), - temp_ldvec3(rhs.temp_ldvec3) + rotation(rhs.rotation) { } @@ -38,7 +37,6 @@ int CoordinateFrame::compare(const Object& rhs_object) const const auto& rhs = static_cast(rhs_object); if ((result = compare_value(name, rhs.name)) != 0) return result; if ((result = compare_value(origin, rhs.origin)) != 0) return result; - if ((result = compare_value(temp_ldvec3, rhs.temp_ldvec3)) != 0) return result; return compare_value(rotation, rhs.rotation); } @@ -48,7 +46,6 @@ void CoordinateFrame::read(Input& input) input.read("name", name); input.read("origin", origin); input.read("rotation", rotation); - input.read("temp_ldvec3" , temp_ldvec3); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -59,7 +56,6 @@ void CoordinateFrame::write(Output& output) const output.write("name", name); output.write("origin", origin); output.write("rotation", rotation); - output.write("temp_ldvec3" , temp_ldvec3); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } From e07953033ff6d31d63fddca781c2d2086a40ff52 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 14:33:44 +0000 Subject: [PATCH 23/26] Ran clang-format --- include/vsg/maths/common.h | 1 - src/vsg/core/Version.cpp | 1 - src/vsg/io/BinaryInput.cpp | 18 ++++++++---------- src/vsg/maths/common.cpp | 2 +- src/vsg/nodes/CoordinateFrame.cpp | 4 ++-- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/include/vsg/maths/common.h b/include/vsg/maths/common.h index dcd617ecf..ef10a4537 100644 --- a/include/vsg/maths/common.h +++ b/include/vsg/maths/common.h @@ -72,5 +72,4 @@ namespace vsg /// return the number of bits supported by the long double implementation - VisualStudio by default 64 bits, stored as 8 bytes, & Linux x86_64 defaults to 80 bits stored as 16bytes, some CPU achitectures support full 128 bits/16 bytes. extern VSG_DECLSPEC uint32_t native_long_double_bits(); - } // namespace vsg diff --git a/src/vsg/core/Version.cpp b/src/vsg/core/Version.cpp index a29825625..7eac7bc00 100644 --- a/src/vsg/core/Version.cpp +++ b/src/vsg/core/Version.cpp @@ -43,5 +43,4 @@ extern "C" return 0; #endif } - } diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index b350f6648..43d16200a 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -88,7 +88,6 @@ void BinaryInput::read(size_t num, Path* value) } } - struct double_64 { uint8_t sign : 1; @@ -107,7 +106,6 @@ struct double_128 }; }; - void BinaryInput::read(size_t num, long double* value) { uint32_t native_type = native_long_double_bits(); @@ -129,7 +127,7 @@ void BinaryInput::read(size_t num, long double* value) std::vector data(num); _read(num, data.data()); - for(auto& v : data) + for (auto& v : data) { *(value++) = v; } @@ -143,7 +141,7 @@ void BinaryInput::read(size_t num, long double* value) if (native_type == 64) { double_64* dest = reinterpret_cast(value); - for(auto& v : data) + for (auto& v : data) { auto& d = *(dest++); d.sign = v.sign; @@ -154,29 +152,29 @@ void BinaryInput::read(size_t num, long double* value) else if (native_type == 80) { double_128* dest = reinterpret_cast(value); - for(auto& v : data) + for (auto& v : data) { auto& d = *(dest++); d.sign = v.sign; d.exponent = v.exponent; // copy fraction and fill in zeros at end - for(int i=0; i<8; ++i) d.mantissa[i] = v.mantissa[i]; + for (int i = 0; i < 8; ++i) d.mantissa[i] = v.mantissa[i]; } } else if (native_type == 128) { double_128* dest = reinterpret_cast(value); - for(auto& v : data) + for (auto& v : data) { auto& d = *(dest++); d.sign = v.sign; d.exponent = v.exponent; // copy fraction and fill in zeros at end - int i=0; - for(; i<8; ++i) d.mantissa[i] = v.mantissa[i]; - for(; i<14; ++i) d.mantissa[i] = 0; + int i = 0; + for (; i < 8; ++i) d.mantissa[i] = v.mantissa[i]; + for (; i < 14; ++i) d.mantissa[i] = 0; } } } diff --git a/src/vsg/maths/common.cpp b/src/vsg/maths/common.cpp index 87f3575d6..c15387ac4 100644 --- a/src/vsg/maths/common.cpp +++ b/src/vsg/maths/common.cpp @@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ -#include #include +#include #include diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 5505fe7cc..82fc23d6a 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -48,7 +48,7 @@ void CoordinateFrame::read(Input& input) input.read("name", name); input.read("origin", origin); input.read("rotation", rotation); - input.read("temp_ldvec3" , temp_ldvec3); + input.read("temp_ldvec3", temp_ldvec3); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -59,7 +59,7 @@ void CoordinateFrame::write(Output& output) const output.write("name", name); output.write("origin", origin); output.write("rotation", rotation); - output.write("temp_ldvec3" , temp_ldvec3); + output.write("temp_ldvec3", temp_ldvec3); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } From bf4790c6657c1a04c4ed6257eb7d73b8600ea80c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 14:35:12 +0000 Subject: [PATCH 24/26] Removed temporary test --- include/vsg/nodes/CoordinateFrame.h | 2 -- src/vsg/nodes/CoordinateFrame.cpp | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index af6ea16af..29a996eb8 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -28,8 +28,6 @@ namespace vsg dvec3 origin; dquat rotation; - ldvec3 temp_ldvec3; - dmat4 transform(const dmat4& mv) const override; public: diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index 82fc23d6a..d8bee299c 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -25,8 +25,7 @@ CoordinateFrame::CoordinateFrame(const CoordinateFrame& rhs, const CopyOp& copyo Inherit(rhs, copyop), name(rhs.name), origin(rhs.origin), - rotation(rhs.rotation), - temp_ldvec3(rhs.temp_ldvec3) + rotation(rhs.rotation) { } @@ -38,7 +37,6 @@ int CoordinateFrame::compare(const Object& rhs_object) const const auto& rhs = static_cast(rhs_object); if ((result = compare_value(name, rhs.name)) != 0) return result; if ((result = compare_value(origin, rhs.origin)) != 0) return result; - if ((result = compare_value(temp_ldvec3, rhs.temp_ldvec3)) != 0) return result; return compare_value(rotation, rhs.rotation); } @@ -48,7 +46,6 @@ void CoordinateFrame::read(Input& input) input.read("name", name); input.read("origin", origin); input.read("rotation", rotation); - input.read("temp_ldvec3", temp_ldvec3); input.read("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); input.readObjects("children", children); } @@ -59,7 +56,6 @@ void CoordinateFrame::write(Output& output) const output.write("name", name); output.write("origin", origin); output.write("rotation", rotation); - output.write("temp_ldvec3", temp_ldvec3); output.write("subgraphRequiresLocalFrustum", subgraphRequiresLocalFrustum); output.writeObjects("children", children); } From ce455e97015e8566582617a8edce8095df6d9c84 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 28 Nov 2024 17:44:10 +0000 Subject: [PATCH 25/26] Added const to resolve cppcheck reporting suggestion. --- src/vsg/io/BinaryInput.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vsg/io/BinaryInput.cpp b/src/vsg/io/BinaryInput.cpp index 43d16200a..0e164f663 100644 --- a/src/vsg/io/BinaryInput.cpp +++ b/src/vsg/io/BinaryInput.cpp @@ -127,7 +127,7 @@ void BinaryInput::read(size_t num, long double* value) std::vector data(num); _read(num, data.data()); - for (auto& v : data) + for (const auto& v : data) { *(value++) = v; } @@ -141,7 +141,7 @@ void BinaryInput::read(size_t num, long double* value) if (native_type == 64) { double_64* dest = reinterpret_cast(value); - for (auto& v : data) + for (const auto& v : data) { auto& d = *(dest++); d.sign = v.sign; @@ -152,7 +152,7 @@ void BinaryInput::read(size_t num, long double* value) else if (native_type == 80) { double_128* dest = reinterpret_cast(value); - for (auto& v : data) + for (const auto& v : data) { auto& d = *(dest++); d.sign = v.sign; @@ -165,7 +165,7 @@ void BinaryInput::read(size_t num, long double* value) else if (native_type == 128) { double_128* dest = reinterpret_cast(value); - for (auto& v : data) + for (const auto& v : data) { auto& d = *(dest++); d.sign = v.sign; From cbdc23981a83bd34aa4ee4c0d60299e83d3f9f2b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Nov 2024 12:36:09 +0000 Subject: [PATCH 26/26] Fixed dates. --- include/vsg/nodes/CoordinateFrame.h | 2 +- src/vsg/nodes/CoordinateFrame.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vsg/nodes/CoordinateFrame.h b/include/vsg/nodes/CoordinateFrame.h index 29a996eb8..11ac99897 100644 --- a/include/vsg/nodes/CoordinateFrame.h +++ b/include/vsg/nodes/CoordinateFrame.h @@ -2,7 +2,7 @@ /* -Copyright(c) 2018 Robert Osfield +Copyright(c) 2024 Robert Osfield Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/src/vsg/nodes/CoordinateFrame.cpp b/src/vsg/nodes/CoordinateFrame.cpp index d8bee299c..213846380 100644 --- a/src/vsg/nodes/CoordinateFrame.cpp +++ b/src/vsg/nodes/CoordinateFrame.cpp @@ -1,6 +1,6 @@ /* -Copyright(c) 2018 Robert Osfield +Copyright(c) 2024 Robert Osfield Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: