Jump to content

2nd World Physics Random Crash


SpiderPig
 Share

Go to solution Solved by Josh,

Recommended Posts

I'm getting random crashes with this code.  Physics in two worlds not supported?

#include "UltraEngine.h"

using namespace UltraEngine;

Vec3 mousepos = Vec3(0.0f);
float move_adjustment = 0.1f;
float move_speed = 1.0f;
float lookspeed = 0.1f;
float looksmoothing = 0.5f;
bool enable_camera = true;

int main(int argc, const char* argv[])
{
    auto displays = GetDisplays();
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);
    auto world = CreateWorld();
    auto framebuffer = CreateFramebuffer(window);

    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetFov(70);
    camera->SetPosition(0, 10, -5);

    auto light = CreateDirectionalLight(world);
    light->SetRotation(35, 45, 0);

    auto floor = CreateBox(world, 10.0f, 0.1f, 10.0f);
    floor->SetPosition(0.0f, -3.0f, 0.0f);
    floor->SetMaterial(LoadMaterial("Materials\\Developer\\bluegrid.mat"));

    auto box = CreateBox(world);
    box->SetCollider(nullptr);
    box->SetPosition(2.0f, 2.0f, 0.0f);

    auto player = CreateCylinder(world);
    player->SetPhysicsMode(PHYSICS_PLAYER);
    player->SetPosition(0.0f, 5.0f, 0.0f);
    player->SetMass(1.0f);

    auto cam_pivot = CreatePivot(world);
    cam_pivot->SetParent(player);
    cam_pivot->SetPosition(0.0f, 1.8f, 0.0f);

    camera->SetParent(cam_pivot);
    camera->SetPosition(0.0f, 0.0f, -3.0f);
    camera->SetDebugPhysicsMode(true);

    auto world_2 = CreateWorld();
    auto f2 = CreateBox(world_2, 10.0f, 0.1f, 10.0f);

    auto b2 = CreateBox(world_2);
    b2->SetMass(1.0f);
    b2->SetPosition(2.0f, 10.0f, 0.0f);

    bool stage = 0;
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyHit(KEY_F2) == true) { camera->SetWireframe(!camera->GetWireframe()); }
        if (window->KeyHit(KEY_F3) == true) { camera->SetDebugPhysicsMode(!camera->GetDebugPhysicsMode()); }
        if (window->KeyHit(KEY_F4) == true) { enable_camera = !enable_camera; }

        if (enable_camera) {
            auto _displaySize = window->GetSize();
            float cx = Round((float)_displaySize.x / 2.0f);
            float cy = Round((float)_displaySize.y / 2.0f);

            auto mpos = Vec3(window->GetMousePosition().x, window->GetMousePosition().y, window->GetMousePosition().z);
            window->SetMousePosition(cx, cy);
            mpos = mpos * looksmoothing + mousepos * (1 - looksmoothing);
            auto dx = (mpos.x - cx) * lookspeed;
            auto dy = (mpos.y - cy) * lookspeed;


            auto camrot = cam_pivot->GetRotation();
            camrot.x += dy;
            camrot.y += dx;
            cam_pivot->SetRotation(camrot);
            mousepos = mpos;
        }

        world_2->Update();
      
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

 

I never thought about it, but this is really bad to do. You've got non-thread-safe Newton calls running on two separate threads at the same time when you do that.

I added this information to the docs:
https://github.com/UltraEngine/Documentation/blob/master/CPP/World_Update.md#remarks

  • Sad 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

7 minutes ago, Josh said:

I never thought about it, but this is really bad to do. You've got non-thread-safe Newton calls running on two separate threads at the same time when you do that.

I added this information to the docs:
https://github.com/UltraEngine/Documentation/blob/master/CPP/World_Update.md#remarks

Ahh, should we only be updating one world at a time or just update A world all the time? This maybe why I'm getting issues with the physics just not working.

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

6 minutes ago, Josh said:

Only call World::Update on one world in your application, ever.

Ok, will fix my code with this advice.

I also recommend making the update function static so future users don't do the same thing. Maybe turn it into a UpdateWorlds() function? 

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

I am adding a check to throw an error if more than one world uses this command..

If I moved all the Newton collider code into the main thread, than multiple worlds updating simultaneously would probably work. Maybe in the future I will do this. (Assuming the recast pathfinding code is also thread-safe.)

  • Like 2

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

46 minutes ago, SpiderPig said:

I think it'll also be needed for moving and turning entities...

Not if these are moved each frame, but you are right the Component::Update call won't be made without it.

You can initialize a world with no physics engine. There is an optional parameter in the CreateWorld() function for this.

  • 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

I'm going to try adding a mutex in the collider Newton shape creation function. That is where this is happening. I think the whole thing will be thread-safe with that change.

I generally do not like to use mutexes and prefer total separation of data, but in this case it makes sense.

  • Like 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

  • Josh locked this topic
Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...