Jump to content

Controller Starts with Offset


SpiderPig
 Share

Go to solution Solved by Josh,

Recommended Posts

I was seeing issues with setting my player controllers position in game so I tried replicating it the best I could here.  With the setup below, setting the mass causes the height to be offset and the player no longer falls.  I thought I was creating the pivot at a different location from the cylinder but if you hit F5 it shows they are at the same location.  I tried giving the pivot it's own collider, but that did nothing.  I assume PHYSICS_PLAYER has it's own collider anyway.  I also tried removing the floor plane.

EDIT : I solved why it wasn't falling.   Stupid me didn't disable the collider on the 'player' model. ;)

There is still the issue of starting with an offset though.  This is what I was seeing in my larger project.  The position reads as 10 units high however it starts lower than that.  In game I've had to add an arbitrary offset to the players height but that won't do forever.

ControllerOffset_001.thumb.jpg.e20440c3d81655ba4a0f572e1c052f51.jpg

#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 = false;

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 world
    auto world = CreateWorld();
    world->SetGravity(0.0f, -0.1f, 0.0f);

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

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetFov(70);
    camera->SetPosition(0, 9, -5);

    //Create a light
    auto light = CreateDirectionalLight(world);
    light->SetRotation(35, 45, 0);
    light->SetRange(-10, 10);

    auto floor = CreatePlane(world, 100.0f, 100.0f);

    auto thing = CreateCylinder(world);
    thing->SetColor(1, 0, 0);
    thing->SetPosition(-2.0f, 10.0f, 0.0f);


    auto controller = CreatePivot(world);
    controller->SetPhysicsMode(PHYSICS_PLAYER);
    controller->SetCollisionType(COLLISION_PLAYER);

    auto player = CreateCylinder(world);
    player->SetParent(controller);
    player->SetColor(0, 1, 0);
    player->SetCollider(nullptr);

    controller->SetPosition(2.0f, 10.0f, 0.0f);
    controller->SetMass(1.0f);
    camera->SetParent(controller);

  	//Reads as the set position above, but appears to start at a lower position.  Gravity has been slowed to better see it at startup.
    auto c_pos = controller->GetPosition(true);
    auto p_pos = player->GetPosition(true);
    Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
    Print("Player Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));

    //Main loop
    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 (window->KeyHit(KEY_F5) == true) {
            auto c_pos = controller->GetPosition(true);
            auto p_pos = player->GetPosition(true);

            Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
            Print("Player Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));
        }

        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 = camera->GetRotation();
            camrot.x += dy;
            camrot.y += dx;
            camera->SetRotation(camrot);
            mousepos = mpos;

            auto speed = 0.1f;
            if (window->KeyDown(KEY_SHIFT) == true) { speed = speed * 10.0f; }
            if (window->KeyDown(KEY_W) == true) { camera->Move(0, 0, speed); }
            else if (window->KeyDown(KEY_S) == true) { camera->Move(0, 0, -speed); }
            if (window->KeyDown(KEY_A) == true) { camera->Move(-speed, 0, 0); }
            else if (window->KeyDown(KEY_D) == true) { camera->Move(speed, 0, 0); }
        }

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

 

Link to comment
Share on other sites

  • SpiderPig changed the title to Controller Starts with Offset
  • 2 weeks later...

The center of the controller is at the foot. The center of a cylinder model is its center. The cylinder model will be offset from the controller pivot by the cylinder height divided by two. Does this address your issue?

#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 = false;

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 world
    auto world = CreateWorld();
    world->SetGravity(0.0f, -0.1f, 0.0f);

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

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetFov(70);
    camera->SetPosition(0, 2, -5);

    //Create a light
    auto light = CreateDirectionalLight(world);
    light->SetRotation(35, 45, 0);
    light->SetRange(-10, 10);

    auto floor = CreateBox(world, 100.0f, 1, 100.0f);

    auto thing = CreateCylinder(world);
    thing->SetColor(1, 0, 0);
    thing->SetPosition(-2.0f, 10.0f, 0.0f);


    auto controller = CreatePivot(world);
    controller->SetPhysicsMode(PHYSICS_PLAYER);
    controller->SetCollisionType(COLLISION_PLAYER);

    auto player = CreateCylinder(world);
    player->SetParent(controller);
    player->SetPosition(0, 0.5, 0);
    player->SetColor(0, 1, 0);
    player->SetCollider(nullptr);

    controller->SetPosition(2.0f, 10.0f, 0.0f);
    controller->SetMass(1.0f);
    //camera->SetParent(controller);

    //Reads as the set position above, but appears to start at a lower position.  Gravity has been slowed to better see it at startup.
    auto c_pos = controller->GetPosition(true);
    auto p_pos = player->GetPosition(true);
    Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
    Print("Player Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));

    //Main loop
    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 (window->KeyHit(KEY_F5) == true) {
            auto c_pos = controller->GetPosition(true);
            auto p_pos = player->GetPosition(true);

            Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
            Print("Player Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));
        }

        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 = camera->GetRotation();
            camrot.x += dy;
            camrot.y += dx;
            camera->SetRotation(camrot);
            mousepos = mpos;

            auto speed = 0.1f;
            if (window->KeyDown(KEY_SHIFT) == true) { speed = speed * 10.0f; }
            if (window->KeyDown(KEY_W) == true) { camera->Move(0, 0, speed); }
            else if (window->KeyDown(KEY_S) == true) { camera->Move(0, 0, -speed); }
            if (window->KeyDown(KEY_A) == true) { camera->Move(-speed, 0, 0); }
            else if (window->KeyDown(KEY_D) == true) { camera->Move(speed, 0, 0); }
        }

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

 

  • 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 think this is due to the fact that Vulkan takes a while to initialize, and the physics simulation is running updates many times before the first frame is rendered.

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 added this before the main loop and it didn't help.  I get about 4k iterations before the loop finishes.

//WHAT FOR THE RENDERER TO START BEFORE STARTING THE GAME
bool started = false;
int it = 0;
while (started == false) {
    world->Render(framebuffer);
    while (PeekEvent()) {
        auto event = WaitEvent();
        if (event.id == EVENT_STARTRENDERER) {
            started = true;
            break;
        }
        it++;
    }
    it++;
}

//Main loop
...

 

Link to comment
Share on other sites

Yes that made a difference.  I removed the pre-loop check and put the world update into a key hit check.

if (window->KeyHit(KEY_SPACE)) {
    world->Update();
}
world->Render(framebuffer);

Upon loading it is slightly offset up, I believe that's the 0.5 offset.

Offset_001.thumb.jpg.4c1a3e6798edf49ad3cd4b5e085b11bd.jpg

After two key hits the cylinder snaps instantly to the lower position.

Offset_002.thumb.jpg.6cd328b3b26d4969fd91a78a9edf9bfe.jpg

Link to comment
Share on other sites

Okay I got it working.  The physics mode should be set AFTER setting the desired position.  Is this correct or is it a bug?

#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 = false;

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 world
    auto world = CreateWorld();
    world->SetGravity(0.0f, -0.1f, 0.0f);

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

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

    //Create a light
    auto light = CreateDirectionalLight(world);
    light->SetRotation(35, 45, 0);
    light->SetRange(-10, 10);

    auto floor = CreateBox(world, 100.0f, 1, 100.0f);

    auto thing = CreateCylinder(world);
    thing->SetColor(1, 0, 0);
    thing->SetPosition(-2.0f, 10.0f, 0.0f);


    auto controller = CreatePivot(world);
    controller->SetCollisionType(COLLISION_PLAYER);
  	//controller->SetPhysicsMode(PHYSICS_PLAYER);

    auto player = CreateCylinder(world);
    player->SetParent(controller);
    player->SetPosition(0, 0.0, 0);
    player->SetColor(0, 1, 0);
    player->SetCollider(nullptr);

    controller->SetPosition(2.0f, 10.0f, 0.0f);
    controller->SetMass(1.0f);
    //camera->SetParent(controller);

    controller->SetPhysicsMode(PHYSICS_PLAYER);
    

    //Reads as the set position above, but appears to start at a lower position.  Gravity has been slowed to better see it at startup.
    auto c_pos = controller->GetPosition(true);
    auto p_pos = player->GetPosition(true);
    auto l_pos = player->GetPosition();
    Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
    Print("Player Global Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));
    Print("Player Local Position : " + String(l_pos.x) + ", " + String(l_pos.y) + ", " + String(l_pos.z));

   /* bool started = false;
    int it = 0;
    while (started == false) {
        world->Render(framebuffer);
        while (PeekEvent()) {
            auto event = WaitEvent();
            if (event.id == EVENT_STARTRENDERER) {
                started = true;
                break;
            }
            it++;
        }
        it++;
    }*/

    //Main loop
    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 (window->KeyHit(KEY_F5) == true) {
            auto c_pos = controller->GetPosition(true);
            auto p_pos = player->GetPosition(true);

            Print("Controller Position : " + String(c_pos.x) + ", " + String(c_pos.y) + ", " + String(c_pos.z));
            Print("Player Position : " + String(p_pos.x) + ", " + String(p_pos.y) + ", " + String(p_pos.z));
        }

        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 = camera->GetRotation();
            camrot.x += dy;
            camrot.y += dx;
            camera->SetRotation(camrot);
            mousepos = mpos;

            auto speed = 0.1f;
            if (window->KeyDown(KEY_SHIFT) == true) { speed = speed * 10.0f; }
            if (window->KeyDown(KEY_W) == true) { camera->Move(0, 0, speed); }
            else if (window->KeyDown(KEY_S) == true) { camera->Move(0, 0, -speed); }
            if (window->KeyDown(KEY_A) == true) { camera->Move(-speed, 0, 0); }
            else if (window->KeyDown(KEY_D) == true) { camera->Move(speed, 0, 0); }
        }

        //if (window->KeyDown(KEY_SPACE)) {
            world->Update();
        //}
        world->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

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

×
×
  • Create New...