Jump to content

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


Dreikblack
 Share

Go to solution Solved by Josh,

Recommended Posts

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;
}

 

Link to comment
Share on other sites

  • 2 weeks later...

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.

Link to comment
Share on other sites

  • 2 weeks later...

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.

Link to comment
Share on other sites

  • Thanks 1

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

Link to comment
Share on other sites

  • 4 weeks later...

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;
}

 

Link to comment
Share on other sites

  • 8 months later...

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • Solution

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.

Link to comment
Share on other sites

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.

 Share

×
×
  • Create New...