Jump to content

GetCollider()->IntersectsPoint() does not work correctly in release mode sometimes


Go to solution Solved by Josh,

Recommended Posts

Posted

I'm not sure what's exact conditions when it does not work but manage to reproduce it when model with detection collider is a green in debug before target brush moves beside its area and in a release is a red (not detecting) 90% of time in same conditions when it should be a green.

btw i don't know why model is not transparent. Somehow it's still working in my game but not in example.

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera    
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.8);
    camera->Turn(35, 0, 0);
    camera->Move(2, 0, -2);
    camera->SetRefraction(true);

    //Create light
    auto light = CreateBoxLight(world);
    light->SetRange(-20, 20);
    light->SetArea(20, 20);
    light->SetRotation(35, 35, 0);

    auto unlitMaterial = CreateMaterial();
    auto unlitShader = LoadShaderFamily("Shaders/Unlit.json");
    unlitMaterial->SetShaderFamily(unlitShader);

    int width = 2, height = 1, length = 3;
    auto model = CreateModel(world);
    auto mesh = model->AddMesh();

    mesh->AddVertex(0, 0, 0); //S
    mesh->AddVertex(-width * 0.5, -height * 0.5, length);//NW
    mesh->AddVertex(width * 0.5, -height * 0.5, length);//NE

    mesh->AddPrimitive(2, 1, 0);//S , NW, NE

    mesh->AddVertex(-width * 0.5, height * 0.5, length);//NW h
    mesh->AddVertex(width * 0.5, height * 0.5, length);//NE h

    mesh->AddPrimitive(0, 3, 4);//S , NW h, NE h

    mesh->AddPrimitive(0, 1, 3);//left

    mesh->AddPrimitive(4, 3, 1); //"face"
    mesh->AddPrimitive(2, 4, 1); //"face"


    mesh->AddPrimitive(0, 4, 2); //"right"

    auto& mat = unlitMaterial;
    mat->SetTransparent(true);
    model->SetMaterial(mat);
    model->SetColor(0.5f, 0.8f, 0, 0.25f);
    model->SetPosition(0, 0, 0);

    auto collider = CreateConvexHullCollider(mesh);
    model->SetCollider(collider);

    Vec3 targetPos(0, 0, 0);
    auto box = CreateBox(world, 0.1f);
    box->SetPosition(targetPos);
    auto mover = box->AddComponent<Mover>();
    mover->movementspeed.x = 1.5f;

    model->Turn(0, 90, 0);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        targetPos = box->GetPosition();
        auto newTargetPos = TransformPoint(targetPos, NULL, model);

        bool isInside = model->GetCollider()->IntersectsPoint(newTargetPos);
        if (isInside)
        {
            model->SetColor(0, 1, 0, 1);
        }
        else {
            model->SetColor(1, 0, 0, 1);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

  • 2 weeks later...
Posted

I can confirm the behavior is different in debug and release, but it looks like this is due to a missing implementation for convex hulls, maybe.

I found this in the header for NewtonCollisionClosestPoint:

Quote

the current implementation of this function does not work on collision trees, or user define collision.

It makes sense that collision trees would not work, because that is a polygon mesh with no volume. However, it seems like convex hulls should be fine. "User-defined" collision is something else in Newton, using a user-defined callback for custom collisions.

Here is my test program:

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera    
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.8);
    camera->Move(3, 0, -2);
    camera->SetDebugPhysicsMode(true);

    auto unlitMaterial = CreateMaterial();
    auto unlitShader = LoadShaderFamily("Shaders/Unlit.json");
    unlitMaterial->SetShaderFamily(unlitShader);

    int width = 2, height = 1, length = 3;
    auto model = CreateModel(world);
    auto mesh = model->AddMesh();

    mesh->AddVertex(0, 0, 0); //S
    mesh->AddVertex(-width * 0.5, -height * 0.5, length);//NW
    mesh->AddVertex(width * 0.5, -height * 0.5, length);//NE

    mesh->AddPrimitive(2, 1, 0);//S , NW, NE

    mesh->AddVertex(-width * 0.5, height * 0.5, length);//NW h
    mesh->AddVertex(width * 0.5, height * 0.5, length);//NE h

    mesh->AddPrimitive(0, 3, 4);//S , NW h, NE h

    mesh->AddPrimitive(0, 1, 3);//left

    mesh->AddPrimitive(4, 3, 1); //"face"
    mesh->AddPrimitive(2, 4, 1); //"face"


    mesh->AddPrimitive(0, 4, 2); //"right"

    world->SetAmbientLight(1);

    //auto& mat = unlitMaterial;
    auto mat = CreateMaterial();
    mat->SetTransparent(true);
    model->SetMaterial(mat);
    //model->SetColor(0.5f, 0.8f, 0, 0.25f);
    model->SetPosition(0, 0, 0);

    auto collider = CreateConvexHullCollider(mesh);
    model->SetCollider(collider);

    Vec3 targetPos(-2, 0, 0);
    auto box = CreateBox(world, 0.1f);
    box->SetPosition(targetPos);
    auto mover = box->AddComponent<Mover>();
    mover->movementspeed.x = 0.2;

    model->Turn(0, 90, 0);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        targetPos = box->GetPosition();
        auto newTargetPos = TransformPoint(targetPos, nullptr, model);

        bool isInside = model->GetCollider()->IntersectsPoint(newTargetPos);
        if (isInside)
        {
            model->SetColor(0, 0.5, 0, 0.5);
        }
        else {
            model->SetColor(0.5,0.5,0.5,0.5);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

My job is to make tools you love, with the features you want, and performance you can't live without.

  • 2 weeks later...
Posted

This example better demonstrates the problem:

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera    
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.8);
    camera->Move(3, 0, -2);
    camera->SetDebugPhysicsMode(true);
    camera->AddComponent<CameraControls>();

    auto unlitMaterial = CreateMaterial();
    auto unlitShader = LoadShaderFamily("Shaders/Unlit.json");
    unlitMaterial->SetShaderFamily(unlitShader);

    int width = 2, height = 1, length = 3;
    auto model = CreateModel(world);
    auto mesh = model->AddMesh();

    mesh->AddVertex(0, 0, 0); //S
    mesh->AddVertex(-width * 0.5, -height * 0.5, length);//NW
    mesh->AddVertex(width * 0.5, -height * 0.5, length);//NE

    mesh->AddPrimitive(2, 1, 0);//S , NW, NE

    mesh->AddVertex(-width * 0.5, height * 0.5, length);//NW h
    mesh->AddVertex(width * 0.5, height * 0.5, length);//NE h

    mesh->AddPrimitive(0, 3, 4);//S , NW h, NE h

    mesh->AddPrimitive(0, 1, 3);//left

    mesh->AddPrimitive(4, 3, 1); //"face"
    mesh->AddPrimitive(2, 4, 1); //"face"


    mesh->AddPrimitive(0, 4, 2); //"right"

    world->SetAmbientLight(1);

    //auto& mat = unlitMaterial;
    auto mat = CreateMaterial();
    mat->SetTransparent(true);
    model->SetMaterial(mat);
    //model->SetColor(0.5f, 0.8f, 0, 0.25f);
    model->SetPosition(0, 0, 0);

    auto collider = CreateConvexHullCollider(mesh);
    model->SetCollider(collider);

    Vec3 targetPos(-1, 0, 0);
    auto box = CreateBox(world, 0.1f);
    box->SetPosition(targetPos);
    auto mover = box->AddComponent<Mover>();
    //mover->movementspeed.x = 0.2;

    model->Turn(0, 90, 0);

    auto ball = CreateSphere(world, 0.055);
    ball->SetColor(1, 0, 0);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        targetPos = box->GetPosition();
        auto newTargetPos = TransformPoint(targetPos, nullptr, model);

        if (window->KeyDown(KEY_RIGHT)) box->Move(0.02, 0, 0);
        if (window->KeyDown(KEY_LEFT)) box->Move(-0.02, 0, 0);
        if (window->KeyDown(KEY_UP)) box->Move(0,0.02, 0);
        if (window->KeyDown(KEY_DOWN)) box->Move(0,-0.02, 0);

        auto p = model->GetCollider()->ClosestPoint(newTargetPos);
        p = TransformPoint(p, model, nullptr);
        ball->SetPosition(p);

        bool isInside = model->GetCollider()->IntersectsPoint(newTargetPos);
        if (isInside)
        {
            model->SetColor(0, 0.5, 0, 0.5);
        }
        else {
            model->SetColor(0.5, 0.5, 0.5, 0.5);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

My job is to make tools you love, with the features you want, and performance you can't live without.

Posted

I made a demo, using the current code from Github. That's all I can do for now.

My job is to make tools you love, with the features you want, and performance you can't live without.

Posted

I can probably insert my own handling for convex hulls, but let's see if Julio responds first.

My job is to make tools you love, with the features you want, and performance you can't live without.

  • 4 weeks later...
Posted

Same problem with Brush

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera    
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.8);
    camera->Move(3, 0, -2);
    camera->SetDebugPhysicsMode(true);

    auto unlitMaterial = CreateMaterial();
    auto unlitShader = LoadShaderFamily("Shaders/Unlit.json");
    unlitMaterial->SetShaderFamily(unlitShader);

    int width = 2, height = 1, length = 3;
    auto brush = CreateBrush(world);

    brush->AddVertex(0, 0, 0); //S
    brush->AddVertex(-width * 0.5, -height * 0.5, length);//NW
    brush->AddVertex(width * 0.5, -height * 0.5, length);//NE

    auto face = brush->AddFace();
    face->AddIndice(0);//S
    face->AddIndice(1);//NW
    face->AddIndice(2);//NE

    brush->AddVertex(-width * 0.5, height * 0.5, length);//NW h
    brush->AddVertex(width * 0.5, height * 0.5, length);//NE h

    face = brush->AddFace();
    face->AddIndice(0);//S
    face->AddIndice(3);//NW h
    face->AddIndice(4);//NE h

    face = brush->AddFace();//left
    face->AddIndice(0);
    face->AddIndice(1);
    face->AddIndice(3);

    face = brush->AddFace();//"face"
    face->AddIndice(1);
    face->AddIndice(2);
    face->AddIndice(4);
    face->AddIndice(3);

    face = brush->AddFace();//right
    face->AddIndice(2);
    face->AddIndice(4);
    face->AddIndice(0);

    //Finalize the coneModel
    brush->Build();

    world->SetAmbientLight(1);

    //auto& mat = unlitMaterial;
    auto mat = CreateMaterial();
    mat->SetTransparent(true);
    brush->SetMaterial(mat);
    //model->SetColor(0.5f, 0.8f, 0, 0.25f);
    brush->SetPosition(0, 0, 0);


    Vec3 targetPos(-2, 0, 0);
    auto box = CreateBox(world, 0.1f);
    box->SetPosition(targetPos);
    auto mover = box->AddComponent<Mover>();
    mover->movementspeed.x = 0.2;

    brush->Turn(0, 90, 0);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        targetPos = box->GetPosition();
        auto newTargetPos = TransformPoint(targetPos, nullptr, brush);

        bool isInside = brush->GetCollider()->IntersectsPoint(newTargetPos);
        if (isInside)
        {
            brush->SetColor(0, 0.5, 0, 0.5);
        }
        else {
            brush->SetColor(0.5, 0.5, 0.5, 0.5);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

  • 8 months later...
Posted

I simplified my example, but the results seem really wrong.

#include "UltraEngine.h"
#include "ComponentSystem.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280 * displays[0]->scale, 720 * displays[0]->scale, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a world
    auto world = CreateWorld();

    //Create a camera    
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.8);
    camera->Move(3, 0, -2);
    camera->SetDebugPhysicsMode(true);
    camera->AddComponent<CameraControls>();

    auto unlitMaterial = CreateMaterial();
    auto unlitShader = LoadShaderFamily("Shaders/Unlit.json");
    unlitMaterial->SetShaderFamily(unlitShader);

    int width = 2, height = 1, length = 3;
    auto model = CreateModel(world);
    auto mesh = model->AddMesh();

    mesh->AddVertex(0, 0, 0); //S
    mesh->AddVertex(length, -height * 0.5, -width * 0.5);//NW
    mesh->AddVertex(length, -height * 0.5, width * 0.5);//NE
    mesh->AddPrimitive(2, 1, 0);//S , NW, NE
    mesh->AddVertex(length, height * 0.5, -width * 0.5);//NW h
    mesh->AddVertex(length, height * 0.5, width * 0.5);//NE h
    mesh->AddPrimitive(0, 3, 4);//S , NW h, NE h
    mesh->AddPrimitive(0, 1, 3);//left
    mesh->AddPrimitive(4, 3, 1); //"face"
    mesh->AddPrimitive(2, 4, 1); //"face"
    mesh->AddPrimitive(0, 4, 2); //"right"
    
    world->SetAmbientLight(1);

    auto mat = CreateMaterial();
    mat->SetTransparent(true);
    model->SetMaterial(mat);
    model->SetPosition(0, 0, 0);
    
    auto collider = CreateConvexHullCollider(mesh);
    model->SetCollider(collider);

    Vec3 targetPos(-1, 0, 0);
    auto box = CreateBox(world, 0.1f);
    box->SetPosition(targetPos);

    auto ball = CreateSphere(world, 0.055);
    ball->SetColor(1, 0, 0);

    model->SetPosition(0, 0, 0);
    model->SetRotation(0, 0, 0);
    model->SetScale(1, 1, 1);

    camera->SetDebugPhysicsMode(true);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyDown(KEY_RIGHT)) box->Move(0.02, 0, 0);
        if (window->KeyDown(KEY_LEFT)) box->Move(-0.02, 0, 0);
        if (window->KeyDown(KEY_UP)) box->Move(0, 0.02, 0);
        if (window->KeyDown(KEY_DOWN)) box->Move(0, -0.02, 0);

        targetPos = box->GetPosition();
        auto closestpoint = model->GetCollider()->ClosestPoint(targetPos);
        ball->SetPosition(closestpoint);

        bool isInside = model->GetCollider()->IntersectsPoint(targetPos);
        if (isInside)
        {
            model->SetColor(0, 0.5, 0, 0.5);
        }
        else {
            model->SetColor(0.5, 0.5, 0.5, 0.5);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

My job is to make tools you love, with the features you want, and performance you can't live without.

Posted

I am considering removing Collider::ClosestPoint and Collider::DistanceToPoint, since they seem to not work with some shapes. These commands are not in the documentation currently.

The Brush class has some of these features and is useful for volume testing.

My job is to make tools you love, with the features you want, and performance you can't live without.

  • Solution
Posted

I will remove this from the API and we can revisit this in the future if it makes sense and can be done.

My job is to make tools you love, with the features you want, and performance you can't live without.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...