Giter Club home page Giter Club logo

mathgeolib's Introduction

MathGeoLib

A C++ library for linear algebra and geometry manipulation for computer graphics.

This repository contains an implementation of my 2015 paper "An Exact Algorithm for Finding Minimum Oriented Bounding Boxes". See http://clb.confined.space/minobb/minobb.html for the full text, and http://clb.confined.space/minobb/test/ModelView.html for a live test build.

juj

mathgeolib's People

Contributors

cadaver avatar dgavedissian avatar jennybc avatar juj avatar merwaaan avatar nicozet avatar stinkfist0 avatar thecomet avatar yszheda avatar zao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mathgeolib's Issues

Forward-declared float2x2 & float2x3 do not exist

Hi,

Not a critical issue but I just got bit because I wrote some code using the float2x2 matrix type that MGL forward-declares but it seems that it does not actually exist :)

(Same thing for float 2x3)

Cheers.

Provide means for easy 16-alignment and std::vector embedding.

Data structures need to be aligned to 16 bytes for efficient SIMD loads and stores.
Also, data structures are often desired to be emdedded inside std::vectors.

If the data structure has declspec(align) members, it cannot be embedded into a std::vector.

As a workaround, provide something like the following scheme:

class float4_unaligned
{
float x,y,z,w;
__m128 sse;
};

typedef __declspec(align (16)) float4_unaligned float4;

// Use case 1 on the stack:
float4 x; // Will be aligned.

// Use case 2 in a vector:
vector<float4_unaligned, custom_16_aligned_allocator> vectorOfFloats; // Will be aligned. See aligned allocator here http://www.velocityreviews.com/forums/t646180-make-stl-containers-allocate-aligned-memory.html
vector<float4_unaligned> vectorOfFloats; // Wouldn't be aligned, and crash at runtime.
vector vectorOfFloats; // Wouldn't probably compile due to http://stackoverflow.com/questions/1281415/error-c2719-val-formal-parameter-with-declspecalign16-wont-be-alig

Polyhedron.cpp // TODO: Do 2D convex hull.

Hi @juj !

I've been using the OBB from your library for an editor I'm writing inside Unity, to get better bounds at what I'm actually picking in my editor:

So far it works well, except for flat objects. After debugging the code I found the following:

// TODO: Do 2D convex hull.

That explains why I'm getting infinite bounds and therefore why nothing is being drawn 😃.

Question:

Do you have any plans to implement a 2D convex hull in the near future ?

Alternatively, how do you have a rough idea on how it should be done ? I could give it a try then.

Thanks !!

TriangleMesh clean memory causing exception if not enable SSE

when a triangleMesh is create without enable SSE, then delete it. like:

TriangleMesh* pMesh = new TriangleMesh();
pMesh->Set(float* p, int numTriangle);
delete pMesh;

it will cause a memory exception, i guess it is the memory allocation and deletion not match.

Thanks.

Plane clipping is too inaccurate (sorry best description)

Given this function where "triangle_" is the library's triangle, the split results are radically different and not even sane. The only sanity they have is positional based on the objects involved.

The "side markings" and all other data are completely unused in the sanity checks, and those are all that I'm worried about. This code should not result in dead zones of zero area polygons (checked against LibGDX in java for a throwaway), but it does result in void spaces when used with the library.

Far too often splitting a triangle by a plane results in a split that does not make sense when flipping the plane. A split of 2 followed by a split of 2, or a split of 1 followed by a split of 1. That involves this library because those splits come from this library's planar functions and triangle functions.

void MeshMerger::SplitTriangles(std::vector<CSGTriangle>& lhs, std::vector<CSGTriangle>& rhs)
    {
        for (unsigned leftIndex = 0; leftIndex < lhs.size(); ++leftIndex)
        {
            CSGTriangle& current = lhs[leftIndex];
            for (unsigned j = 0; j < rhs.size(); ++j)
            {
                // Don't allow a polygon to split a product more than once, triangle-to-triangle test is false alarm
                if (rhs[j].lastSplitter_ == leftIndex)
                    continue;
                if (!current.triangle_.Intersects(rhs[j].triangle_))
                    continue;
                Triangle a0, b0;
                Triangle a1, b1;
                Plane splitPlane = current.triangle_.PlaneCCW();
                int ret = splitPlane.Clip(rhs[j].triangle_, a0, b0);
                if (ret > 0)
                {
                    CSGTriangle aa0;
                    aa0.triangle_ = a0;
                    aa0.lastSplitter_ = leftIndex;
                    aa0.backSideMarked_ = 1;
                    rhs.push_back(aa0);
                    if (ret == 2)
                    {
                        CSGTriangle bb0;
                        bb0.backSideMarked_ = 1;
                        bb0.lastSplitter_ = leftIndex;
                        bb0.triangle_ = b0;
                        rhs.push_back(bb0);
                    }

                    splitPlane.ReverseNormal();
                    ret = splitPlane.Clip(rhs[j].triangle_, a1, b1);
                    if (ret > 0)
                    {
                        CSGTriangle aa1;
                        aa1.triangle_ = a1;
                        aa1.backSideMarked_ = -1;
                        aa1.lastSplitter_ = leftIndex;
                        rhs.push_back(aa1);
                        if (ret == 2)
                        {
                            CSGTriangle bb1;
                            bb1.backSideMarked_ = -1;
                            bb1.triangle_ = b1;
                            bb1.lastSplitter_ = leftIndex;
                            rhs.push_back(bb1);
                        }
                    }

                    // Remove the triangle that we have split
                    rhs.erase(rhs.begin() + j);
                    --j;
                }
            }
        }
    }

The intersection (Polygon/Polyhedron) FaceContains function could give false intersection result

on code line:
if (Abs(p1.y) < epsilon)
p0.y = -epsilon; // Robustness check - if the ray (0,0) -> (+inf, 0) would pass through a vertex, move the vertex slightly.

Not sure why it is (p0.y = -epsilon) instead of (p1.y = -epsilon), this would cause subsequent codes:
if (p0.x > 1e-3f && p1.x > 1e-3f)
++numIntersections;
increase the intersection by 1 which is incorrected, give the input:
Test Face: coordinates [7680, 6801, 2050] [7715, 6801, 2050] [7715 6801 0]
Test Point: coordinates [7529.18408, 6801, 0 ]
PolygonThickness: [0.00100000005]

Missing Feature in Quadtree?

Hi - thanks for your time developing this library. I've noticed you wrote a robust Quadtree class. I'd like to use it but I need the nearest neighbor function which is hidden behind a MATH_CONTAINERLIB_SUPPORT macro, which i think only requires MaxHeap. Would this be something you would consider publicly adding to the library?

Build instructions for SSE + Emscripten.

MathGeoLib at http://clb.demon.fi/MathGeoLib/nightly/ is now worked to build with Emscripten juj/sse1 branch from https://github.com/juj/emscripten/tree/sse1 . It can be used to unit test and benchmark SSE support in Emscripten. A quick setup guide:

Setting up MathGeoLib:

  1. Set up Emscripten e.g. via emsdk and use the branch https://github.com/juj/emscripten/tree/sse1
  2. git clone https://github.com/juj/MathGeoLib.git

Build structure follows traditional CMake out-of-source builds, so to configure different build types, do the following in MathGeoLib root directory:

  1. mkdir new_directory_for_my_build
  2. cd new_directory_for_my_build
  3. cmake <options> ..

Where the cmake configure line with <options> is:

  • Build for native benchmark runs with SSE1 support (no SSE2 or newer, replace with -DMATH_SSE2=1 or e.g. -DMATH_AVX=1 for that):

    cmake -DMATH_TESTS_EXECUTABLE=1 -DMATH_SSE=1 -DCMAKE_BUILD_TYPE=Release ..
    
  • Build for native debug runs with SSE1 support:

    cmake -DMATH_TESTS_EXECUTABLE=1 -DMATH_SSE=1 -DCMAKE_BUILD_TYPE=Debug -DFAIL_USING_EXCEPTIONS=1 ..
    

To build with Emscripten, set up Emscripten first, e.g. via the Emscripten SDK, and have your Emscripten tools set up in PATH (source emsdk_env.sh/.bat in your shell if using emsdk), and then

  • Build for Emscripten benchmark runs with SSE1 support:

    emcmake cmake -DMATH_TESTS_EXECUTABLE=1 -DMATH_SSE=1 -DCMAKE_BUILD_TYPE=Release ..
    
  • Build for Emscripten debug runs with SSE1 support:

    emcmake cmake -DMATH_TESTS_EXECUTABLE=1 -DMATH_SSE=1 -DCMAKE_BUILD_TYPE=Debug -DFAIL_USING_EXCEPTIONS=1 ..
    

To build and run the output, do in native:

  1. make/mingw32-make/msbuild/xcodebuild depending on your OS and target IDE
  2. Run ./MathGeoLib

and in Emscripten:

  1. make/mingw32-make depending on your OS
  2. run generated MathGeoLib.html or if you want to run in shell, then the file MathGeoLib.js

(TODO: incorporate these into the main docs)

Convert matrix representation from row major to column major.

Profiling shows that Matrix*vector operations can be implemented faster with SSE when the matrix is stored in column major order. The current order is row major.

Convert the representation from row major to column major to implement faster M*v path.

Unexpected results with Polyhedron::Triangulate()

Hi,

When tesselating a polyhedron with a single concave face, I sometimes get unexpected results, like in the following screenshot:

mglbug

(I was under the impression that MathGeoLib's supports producing triangles from concave polygons but I haven't been able to find any formal confirmation in the code or the documentation, so please correct me if I'm wrong about this!)

Any idea?
Thanks.

Not getting same results from Emscripten version as C++ code

It looks fine at http://clb.demon.fi/minobb/test/ModelView.html.
But I downloaded and compiled latest master and the ConvexHull
When the following code executes:

math::vec* vecarray = new math::vec[uniqueVertex.size()];

int i=0;

foreach (const QVector3D& v, uniqueVertex)

{

    vecarray[i++] = math::vec(v.x(), v.y(), v.z());

}

math::OBB ob = math::OBB::OptimalEnclosingOBB(vecarray, uniqueVertex.size());

I get this error:
Boundary is not connected: there should be edge 33-37 in the boundary!
"false in C:\Users\jason6616\Desktop\dev\MathGeoLib-master\src\Geometry\Polyhedron.cpp:2038"
"Assumption "MATH_NS::IsFinite(m_0c) in C:\Users\jason6616\Desktop\dev\MathGeoLib-master\src\Math\flo"... (unknown length)
"Assumption "MATH_NS::IsFinite(m_1c) in C:\Users\jason6616\Desktop\dev\MathGeoLib-master\src\Math\flo"... (unknown length)
"Assumption "dirArray in C:\Users\jason6616\Desktop\dev\MathGeoLib-master\src\Math\float3x4.cpp:1204""... (unknown length)

Results from online demo:
Convex hull computed in 439.05 msecs, got 40 vertices, 63 faces and 101 edges.
Minimum volume OBB computed in 629.11 msecs. Volume: 0.493_15.711_0.493=3.81337
Minimum volume OBB: Center pos: (309.033, 284.244, 37.335); Diameter: (0.493, 15.711, 0.493)
Local Axes: X:(-0.704, -0.062, 0.707); Y:(-0.087, 0.996, 0.000); Z:(-0.705, -0.062, -0.707)
Defining corners: c0: (310.064, 276.449, 37.335); cX: (309.717, 276.419, 37.683); cY: (308.695, 292.100, 37.335); cZ: (309.717, 276.419, 36.986)

Some datasets work just fine though...
using MinGW 4.8 on Win 7
Any ideas?

Here is the dataset i am using:

308.1120 292.0490 37.2578
308.1470 292.0520 37.1883
309.5160 276.4010 37.1883
309.4810 276.3980 37.2578
308.2020 292.0570 37.1332
309.5710 276.4060 37.1332
308.2710 292.0630 37.0978
309.6410 276.4120 37.0978
308.3480 292.0690 37.0856
309.7170 276.4190 37.0856
308.4250 292.0760 37.0978
309.7940 276.4260 37.0978
308.4940 292.0820 37.1332
309.8630 276.4320 37.1332
308.5490 292.0870 37.1883
309.9180 276.4370 37.1883
308.5840 292.0900 37.2578
309.9540 276.4400 37.2578
308.5960 292.0910 37.3349
309.9660 276.4410 37.3349
308.5840 292.0900 37.4119
309.9540 276.4400 37.4119
308.5490 292.0870 37.4814
309.9180 276.4370 37.4814
308.4940 292.0820 37.5366
309.8630 276.4320 37.5366
308.4250 292.0760 37.5720
309.7940 276.4260 37.5720
308.3480 292.0690 37.5842
309.7170 276.4190 37.5842
308.2710 292.0630 37.5720
309.6410 276.4120 37.5720
308.2020 292.0570 37.5366
309.5710 276.4060 37.5366
308.1470 292.0520 37.4814
309.5160 276.4010 37.4814
308.1120 292.0490 37.4119
309.4810 276.3980 37.4119
308.1000 292.0480 37.3349
309.4690 276.3970 37.3349
308.3480 292.0690 37.3349
309.7170 276.4190 37.3349

aabb capsule intersection bug

{
    math::vec minPoint = math::vec(  438.420929 , 805.586670 , 493.709167 );
    math::vec maxPoint = math::vec( 443.420929 ,810.586670 ,498.709167 );
    math::AABB aabb(minPoint, maxPoint);

    math::vec a( 479.665222 ,-30.0000000,509.737244 );
    math::vec b( 479.665222 , 1530.00000 , 509.737244 );

    math::Capsule cylinder(a, b, 37.6882935);

    if (cylinder.Intersects(aabb))
    {
        std::cout << "MathGeoLib intersects\n";
    }
}

Error: Assumption ""insideSimplex || dist <= d[4] + 1e-4f * Max(1.f, d[4], dist)", d[4]: 0.0750471, dist: 0.213954, insideSimplex: 0, minDistIndex: 11 in \src\Algorithm\GJK.cpp:237" failed! in file \src\Algorithm\GJK.cpp, line 237!

Add support for convex polyhedron.

Add a separate class named Convex, ConvexPolyhedron or PlaneBoundedVolume, which is a stored as a list of planes instead of vertex-polygon list representation. This allows considerably faster SAT tests against other primitives.

Complex.cpp?

Hi, just wondering if Complex.cpp actually exists as it seems to be missing in the Math directory.

OBB Intersects issue

Hey There,

I found that there might be an issue in Method [OBB::Intersects(const OBB &b, float epsilon)]

Please see below code:

    float3 min_A(0,0,0);
float3 max_A(1,1,1);

    float3 min_B(0,0,0);
    float3 max_B(2,2,2);

    AABB a(min_A, max_A);
    AABB b(min_B, max_B);

    OBB oa(a);
    OBB ob(b);

    float4x4 transMatrix(0.00000000000000, 0.00000000000000, 1.00000000000000, 0.00000000000000,
                     -0.50000000000000,  0.86602540378444, 0.00000000000000, 0.00000000000000,
                     -0.86602540378444, -0.50000000000000, 0.00000000000000, 0.00000000000000,
                     0.00000000000000,  0.00000000000000, 0.00000000000000, 1.00000000000000);

    ob.Transform(transMatrix);

    bool res = oa.Intersects(ob, 1e-7f);



    On principle, these 2 OBB should be overlap on (0,0,0), but it returned a "false", not sure if it is an issue. Thanks a lot.

Add Cone class.

Sometimes Cone queries are more interesting than Frustum queries, so consider adding support for a Cone class as well.

Log spam on MSVC maximum warning level when MATH_SIMD has not been defined

The recent change in MathGeoLibFwd.h to define ALIGN16,32,64 in advance causes the following kind of log spam on MSVC maximum warning level, when MATH_SIMD is not defined:

2>d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\simd.h(355): warning C4005: 'ALIGN16' : macro redefinition
2>          d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\../MathGeoLibFwd.h(105) : see previous definition of 'ALIGN16'
2>d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\simd.h(356): warning C4005: 'ALIGN32' : macro redefinition
2>          d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\../MathGeoLibFwd.h(106) : see previous definition of 'ALIGN32'
2>d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\simd.h(357): warning C4005: 'ALIGN64' : macro redefinition
2>          d:\projects\tundra-urho3d\deps-vs2010-x86\mathgeolib\build\include\mathgeolib\math\../MathGeoLibFwd.h(107) : see previous definition of 'ALIGN64'

How to build the lib with visual studio 2017

Hi guys,

I have seen there is a bat file to generate the visual studio project. But the project is only for the testing and has only one file. How could I get the visual project to compile the whole lib in visual studio 2017?

Thank you..
Regards
Eric

Finish Polygon and Polyhedron classes.

Both classes Polygon and Polyhedron are implemented somewhat naively, and several collision tests are written in a very slow manner, and the functionality not completely tested.

Finalize these class structures.

Matrix Calc issue

Hey Juj,

Thanks for your quick response, while I create a OBB instance, I found below 2 issues,

Line 629 of file "OBB.cpp", Mathod [void OBBTransform(OBB &o, const Matrix &transform)] 

1.  I have tried many matrix for testing, and every time I couldn't get the OBB I expecting after rotated. 
     (the position of OBB is NOT equal to the result calculated by MATLAB or written calculation )

2.  There input a 4x4 matrix, it should include the translate parameter, but the OBB will not do the translate job.

Maybe we should use CrossProduct instead DotProduct ?

Documentation Website is not working(?)

We're a group of students that would like to use your math library for a game engine creation, we've been using it last years but the website is not working any more.

bug:aabb capsule intersection, gjk.cpp wrong assert,wrong calculation result

  {
        math::vec minPoint = math::vec(1549.69849 , 639.203125 , 1115.08582);
        math::vec maxPoint = math::vec(1554.69849 , 644.203125 ,1120.08582);
        math::AABB aabb(minPoint, maxPoint);

        math::vec a(1072.35388 , 1130.68018, -477.690887);
        math::vec b(1699.54614, 490.913147,1637.29395);

        math::Capsule cylinder(a, b, 4.36077833);

        if (cylinder.Intersects(aabb))
        {
            std::cout << "MathGeoLib intersects\n";
        }
    }

     {
         gte::Vector<3, float> minPoint({ 1549.69849, 639.203125, 1115.08582 });
         gte::Vector<3, float>  maxPoint({ 1554.69849, 644.203125, 1120.08582 });
         gte::AlignedBox3<float>   aabb(minPoint, maxPoint);

         gte::Vector<3, float> a({ 1072.35388, 1130.68018, -477.690887 });
         gte::Vector<3, float> b({ 1699.54614, 490.913147, 1637.29395 });
         gte::Vector<3, float> dir = a - b;    gte::Normalize(dir);
         float height = gte::Length(a - b);

         gte::Line3<float> axis(a, dir);
         gte::Cylinder3<float> cylinder(axis, 4.36077833, height);

         gte::TIQuery<float, gte::AlignedBox3<float>, gte::Cylinder3<float> > query;
         gte::TIQuery<float, gte::AlignedBox3<float>, gte::Cylinder3<float> >::Result res = query(aabb, cylinder);
         if (res.intersect)
         {
             std::cout << "gte intersects\n";
         }

     }

Error: Dot(tri023Normal, d01) <= 0.f in MathGeoLib_20190522\src\Algorithm\GJK.cpp:249
terminal output:MathGeoLib intersects。

MathGeoLib: master 20190522, after #55 .

I think this is a bug in GJK algorithm。

uh... I've checked agian. It seems that GeometricToolsEngine3p25 also gives wrong answer.
If the radius of gte::Cylinder3 cylinder(axis, 4.36077833, height) increases, it still reports no intersection.

Set3x3PartRotateEulerYZX and ExtractEulerYZX need to modify in Matrix.inl

According to https://www.geometrictools.com/Documentation/EulerAngles.pdf ( 2.4 Factor asRyRzRx ), Set3x3PartRotateEulerYZX and ExtractEulerYZX need to modify in Matrix.inl

//1. modify Set3x3PartRotateEulerYZX
template<typename Matrix>
void Set3x3PartRotateEulerYZX(Matrix &m, double &y, double &z, double &x)
{
	///\todo Vectorize to compute 4 sines+cosines at one time.
	double cx, sx, cy, sy, cz, sz;
	SinCos(x, sx, cx);
	SinCos(y, sy, cy);
	SinCos(z, sz, cz);

	m[0][0] =  cy*cz; m[0][1] = sx*sy - cx*cy*sz; m[0][2] = cx*sy + cy*sx*sz;
	m[1][0] =     sz; m[1][1] =            cx*cz; m[1][2] =           -cz*sx;
	m[2][0] = -cz*sy;  m[2][1] = cy*sx + cx*sy*sz; m[2][2] = cx*cy - sx*sy*sz;
}
//2.Modify ExtractEulerYZX
template<typename Matrix>
void ExtractEulerYZX(Matrix &m, double &y, double &z, double &x)
{
	if (m[1][0] < 1.f)
	{
		if (m[1][0] > -1.f)
		{
			z = asin(m[1][0]);
			y = atan2(-m[2][0], m[0][0]);
			x = atan2(-m[1][2], m[1][1]);
		}
		else
		{
			// Not a unique solution.
			z = -pi/2.f;
			y = -atan2(m[2][1], m[2][2]);
			x = 0;
		}
	}
	else
	{
		// Not a unique solution.
		z = pi/2.f;
		y = atan2(m[2][1], m[2][2]);
		x = 0;
	}
}

Add float4x4::GLOrthoProjRH/LH.

There are functions float4x4::D3DOrthoProjRH and D3DOrthoProjLH, but no equivalents for GLOrthoProjRH/LH. Add those functions.

The main difference is that GL expects output in the range z=[-1,1] whereas D3D expects the output in the range z=[0,1].

Unimplemented functions defined in headers

When doing automated script bindings based on Doxygen header file xml output I noticed the following functions are defined but don't have an implementation:

static void float4::Orthogonalize(const float4 &a, float4 &b);
static void float4::Orthogonalize(const float4 &a, float4 &b, float4 &c);
float Plane::Distance(const float4 &point) const;

Polyhedron against plane split

Hello! Thanks for such a great library.
Is there any plans for supporting polyhedron clip by plane?
Sorry for bad English.

Sphere::RandomPointOnSurface has a high rate of failure for smaller spheres

I noticed some serious startup delay in my code in debug mode and did some random breaks to see where the time was spent.
On the first try, I hit the "astronomically small probability" in Sphere::RandomPointOnSurface, which ends up constructing a rather expensive stack trace which ends up in the void as I have no console attached.

I enter this code via float3::RandomDir(lcg, 0.1f), so r is 0.1. This means that the lenSq < r*r is going to be way less likely in my test case than for the unit sphere.
Doing some highly unscientific sampling, I end up at around 700-900 iterations when succeeding, and most of the time, not succeeding at all.

support multiplication of two float3 operands

Hi,

Thanks for your work.

I have a C code with variables in float3 data type. So I included float3.h header file in my code and compiled it with g++. It seems that the library doesn't support the multiplication of two float3 operands, am I right?

For example for the following line:
((float3*)((float*)compute1 + (0)))[0] = (((float3*)((float*)compute1 + (0)))[0] + (((float3*)((float*)placeholder + (0)))[0] * ((float3*)((float*)placeholder1 + ((y_outer_x_outer_fused * 3))))[0]));

I get this error:

error: no match for ‘operator*’ (operand types are ‘math::float3’ and ‘math::float3’)
       ((float3*)((float*)compute1 + (0)))[0] = (((float3*)((float*)compute1 + (0)))[0] + (((float3*)((float*)placeholder + (0)))[0] * ((float3*)((float*)placeholder1 + ((y_outer_x_outer_fused * 3))))[0]));
                                                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

KdTree not working with a single item/multiple items that cannot be split

Hi,

It seems that MathGeoLib's KdTree doesn't work when a single object has been added (also when several objects have been added but they cannot be split into leaves at the root).

This looks like it's due to the SplitLeaf() method aborting the building process when it cannot separate objects. When this happens at the root node, it leaves us with a KdTree in an invalid state : the root node is not considered a leaf even though it contains objects and this breaks the queries that will come later due to assertions in DEBUG builds and numerical errors because splitPos/splitAxis have invalid values.

Minimal reproducible example:

// Build the tree

KdTree<Triangle> tree;

Triangle triangle(float3::zero, float3::unitX, float3::unitY);

tree.AddObjects(&triangle, 1);
tree.Build();

// Query

AABB bbox(float3::one * -10, float3::one * 10);

tree.AABBQuery(bbox, [&](KdTree<Triangle>& tree, KdTreeNode& leaf, const AABB& aabb)
{
        auto bucket = tree.Bucket(leaf.bucketIndex);
        auto triangle = tree.Object(*bucket);

         // ... do stuff with triangle ...

         return false;
});

A possible fix could be to support this case explicitly in AABBQuery() before checking left & right children. Something like this:

while(stackSize > 0)
{
	KdTreeNode *cur = stack[--stackSize];
	//assert(!cur->IsLeaf());

        // If the node is a leaf, directly call the callback on it
        if (cur->IsLeaf())
        {
            leafCallback(*this, *cur, aabb);
            return;
        }

        // Deal with with children normally

        ...
}

I might even be better to deal with this case in Build() but I'm not familiar enough with the class to be sure which strategy is best.

Any thoughts about this?
Should I propose a PR?

Triangle - AABB Intersection bug?

Triangle triangle{ float3{0.0f, 0.0f, 0.0f}, float3{1.0f, 0.0f, 0.0f}, float3{0.0f, 1.0f, 0.0f} };
AABB aabb{ float3{-2.0f, -2.0f, -2.0f}, float3{2.0f, 2.0f, 2.0f} };

bool does_intersect = triangle.Intersects(aabb);

The triangle is contained in the AABB but does_intersect is false. It seems to be a problem when the triangle is parallel to the bounding box. I have SSE disabled.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.