SpiderPig Posted August 24, 2023 Share Posted August 24, 2023 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. #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 More sharing options...
Josh Posted September 5, 2023 Share Posted September 5, 2023 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; } 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 More sharing options...
SpiderPig Posted September 5, 2023 Author Share Posted September 5, 2023 Ah that makes sense. It didn't solve it though. In your example if you raise the cameras height to 8 you'll be able to see the green player cylinder still starts a few units below the other cylinder even though the console output says there now only 0.5 units apart. Link to comment Share on other sites More sharing options...
Josh Posted September 5, 2023 Share Posted September 5, 2023 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 More sharing options...
SpiderPig Posted September 5, 2023 Author Share Posted September 5, 2023 Is it possible for me to start physics when I want to rather than it being automatic? I could load all aspects of the game and then after a few frames are rendered start the physics thread. Link to comment Share on other sites More sharing options...
Josh Posted September 5, 2023 Share Posted September 5, 2023 Yes, you can wait until the EVENT_STARTRENDERER event occurs before calling World::Update. 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 More sharing options...
SpiderPig Posted September 5, 2023 Author Share Posted September 5, 2023 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 More sharing options...
Josh Posted September 5, 2023 Share Posted September 5, 2023 It's also possible that the first frame might take a long time to render, maybe? Try setting it so world:Update only gets called if a key is down. 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 More sharing options...
SpiderPig Posted September 5, 2023 Author Share Posted September 5, 2023 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. After two key hits the cylinder snaps instantly to the lower position. Link to comment Share on other sites More sharing options...
Josh Posted September 5, 2023 Share Posted September 5, 2023 Is that the correct behavior? 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 More sharing options...
SpiderPig Posted September 5, 2023 Author Share Posted September 5, 2023 I don't think so. The position readout seems to be accurate but the fact that it jumps down like that as soon as it starts updating shouldn't happen I think. It should start falling slowly from the higher position. Link to comment Share on other sites More sharing options...
SpiderPig Posted September 6, 2023 Author Share Posted September 6, 2023 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 More sharing options...
Solution Josh Posted September 6, 2023 Solution Share Posted September 6, 2023 You are correct, this is a bug. I am compiling a new build for you now... 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 More sharing options...
Recommended Posts