Jump to content

Josh

Staff
  • Posts

    23,314
  • Joined

  • Last visited

Everything posted by Josh

  1. Josh

    2D Depth

    WIdget::SetParent has an optional position parameter for this purpose: https://www.ultraengine.com/learn/Widget_SetParent?lang=cpp "Position" here means position in the child list, not the sprite depth value.
  2. If you are only rotating on one axis you can use SetRotation instead of Turn and the Euler angles you set won't be modified. Or you can just store the pitch in a variable, and increment that and call SetRotation every frame using that variable for the pitch.
  3. I can't say what the problem was but I clean and rebuild of the engine fixed it. The update is available now on 1.0.1. BTW, it seems a lot of your colliders consist of 1-2 triangles. This is probably very inefficient and it would be better if they were in bigger pieces, but that should still not cause a crash like you were experiencing.
  4. Updated 1.0.1 Fixed mesh collider crash Leadwerks material loader will now enable alpha masking if the "leaves" shader is detected
  5. I'm just curious. Something like this would make a nice example. It is possible to make your units affect the navigation mesh when they are stopped. This would make other units navigate around them instead of pushing through the crowd.
  6. Yes, you answered your own question. Euler angles are easy for humans to understand, but they cannot accurately describe all rotations. When the pitch approaches 90 degrees, there is no way to describe the roll accurately, because at that angle the pitch and roll are the same. This is called Gimbal lock: This has even caused problems in space missions. I can't find the exact clip, but they talk about this in the movie "Apollo 13". Quaternions are an exact description, but you need a degree in mathematics to understand them. In fact there is an entire book I hope to some day read named simply "Visualizing Quaternions": https://www.elsevier.com/books/visualizing-quaternions/hanson/978-0-12-088400-1 Each entity stores its rotation in both Euler and quaternion form, and these are kept in sync whenever rotation changes. The Turn method uses quaternions to accurately turn the entity, and then fills in the entity's Euler rotation value by converting it from the resulting quaternion. So everything is correct.
  7. Updated 1.0.1 Shader adjustments for SSR with classic specular model
  8. That looks awesome. How are you handling the logic? Do you use the component system or are you treating the soldiers as one big crowd?
  9. I need the code anyways, so might as well send me the project.
  10. I have uploaded my build of Newton 3 here: https://github.com/UltraEngine/NewtonDynamics3 It would probably be better for me to debug your project. I don't think you will get any useful information out of the Newton debug output.
  11. Yeah, the sprite creation code uses a small offset and when scaled that vertex offset will no longer be correct. I am glad I postponed the pixel alignment issues reported with the GUI system, because this all needs to be solved the same way...
  12. Here you go. I had problems using a wireframe rect. I suspect the scaling breaks the pixel-perfect alignment. I will look into that now, but this gives you enough to work with: #include "UltraEngine.h" using namespace UltraEngine; #define MB_LEFT 1 int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create window auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0]); //Create framebuffer auto framebuffer = CreateFramebuffer(window); //Create world auto world = CreateWorld(); //Create a 3d camera auto camera = CreateCamera(world); camera->SetFov(70); camera->SetPosition(0, 50, 0); camera->SetRotation(45, 0, 0); camera->SetClearColor(0.125); //Sunlight auto light = CreateDirectionalLight(world); light->SetRotation(45, 35, 0); light->SetColor(2); //Create terrain auto terrain = CreateTerrain(world, 512); terrain->LoadHeightmap("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Terrain/512.r16"); terrain->SetScale(1, 100, 1); //Create base material auto ground = CreateMaterial(); auto diffusemap = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/river_small_rocks_diff_4k.dds"); auto normalmap = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/river_small_rocks_nor_gl_4k.dds"); ground->SetTexture(diffusemap, TEXTURE_DIFFUSE); ground->SetTexture(normalmap, TEXTURE_NORMAL); terrain->SetMaterial(ground); //Create paint material auto rocks = CreateMaterial(); diffusemap = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/Rocks_Dirt_Ground_2k.dds"); normalmap = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/Rocks_Dirt_Ground_2k_dot3.dds"); auto dispmap = LoadTexture("https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets/Materials/Ground/Rocks_Dirt_Ground_2k_disp.dds"); rocks->SetTexture(diffusemap, TEXTURE_DIFFUSE); rocks->SetTexture(normalmap, TEXTURE_NORMAL); rocks->SetTexture(dispmap, TEXTURE_DISPLACEMENT); //Apply material based on terrain slope for (int x = 0; x < terrain->resolution.x; ++x) { for (int y = 0; y < terrain->resolution.y; ++y) { float slope = terrain->GetSlope(x, y); if (slope > 15.0f) { float wt = Min((slope - 15.0f) / 10.0f, 1.0f); terrain->SetMaterial(x, y, rocks, wt); } } } //Load a font auto font = LoadFont("Fonts/arial.ttf"); //Create user interface auto ui = CreateInterface(world, font, framebuffer->size); ui->background->SetColor(0, 0, 0, 0); ui->SetRenderLayers(2); auto testpanel = CreatePanel(20, 20, 200, 200, ui->background); //Create camera auto uiCamera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); uiCamera->SetPosition(float(framebuffer->size.x) * 0.5f, float(framebuffer->size.y) * 0.5f, 0); uiCamera->SetClearMode(ClearMode::CLEAR_DEPTH); uiCamera->SetRenderLayers(2); uiCamera->SetDepthPrepass(false); //auto rect = CreatePanel(0, 0, 0, 0, ui->root, PANEL_BORDER); //rect->SetColor(Vec4(0, 0.f, 0.f, 0.f), WIDGETCOLOR_BACKGROUND); //rect->SetColor(Vec4(255, 255, 255.f, 255.f), WIDGETCOLOR_BORDER); auto mouseDown = false; iVec2 clickPos; auto rect = CreateSprite(world, 1, 1, false); rect->SetRenderLayers(2); auto mtl = CreateMaterial(); mtl->SetColor(0, 1, 1, 0.25); mtl->SetTransparent(true); mtl->SetShaderFamily(LoadShaderFamily("Shaders/Unlit.json")); rect->SetMaterial(mtl); while (true) { while (PeekEvent()) { const Event ev = WaitEvent(); switch (ev.id) { case EVENT_WINDOWCLOSE: { if (ev.source == window) { return 0; } break; } case EVENT_MOUSEDOWN: { const auto button = ev.data; if (!mouseDown && button == MB_LEFT) { mouseDown = true; clickPos = { window->GetMousePosition().x, window->GetMousePosition().y }; } break; } case EVENT_MOUSEUP: { const auto button = ev.data; if (button == MB_LEFT) { rect->SetScale(0); //rect->SetShape(0, 0, 0, 0); mouseDown = false; } break; } default: { ui->ProcessEvent(ev); break; } } } if (mouseDown) { auto mousePosition = window->GetMousePosition(); float h = Abs(clickPos.y - mousePosition.y) + 1; rect->SetPosition(Min(mousePosition.x, clickPos.x), framebuffer->size.y - Min(mousePosition.y, clickPos.y) - h); rect->SetScale(Abs(clickPos.x - mousePosition.x) + 1, h, 1); //rect->SetShape(Min(mousePosition.x, clickPos.x), // Min(mousePosition.y, clickPos.y), // Abs(clickPos.x - mousePosition.x) + 1, // Abs(clickPos.y - mousePosition.y) + 1); } world->Update(); world->Render(framebuffer); } return 0; }
  13. I can tell exactly what is happening. When you change the size of the widget, the GUI system creates a new sprite and deletes the old one. But the culling thread does not create a new visibility list that contains the new sprite until it receives its existence from the main thread and returns another visibility set to the renderer. So you have this period where the old sprite disappears but the new one is not yet visible. A way to eliminate this would be to create a wireframe sprite and just rescale it when the rectangle changes size.
  14. It is. If you download the last versiion of Newton 3.14 on Github you can compile a DLL and run your app to debug the DLL.
  15. I don't know if it's perfect, but your example no longer causes any problem.
  16. An update is available now which fixes this. Let me know if you see any other problems.
  17. If you can reliably produce the error please give me some code to run.
  18. Updated 1.0.1 Fixed bug where changing color scheme did not affect menus or combobox windows Added stricter checking of minimum mesh collider triangle size
  19. If they are that small they will not contribute to collision anyways, so don't worry about it. I'll have an update later today.
  20. I set both to 0.01. I've brought this up with Julio before and his response was basically "don't do that".
  21. I added a check for minimum triangle area and edge lengths. I dislike the fact that this is not exact. Please let me know if you encounter this again after today's update.
  22. This will be fixed in an update today. I also found combo boxes had the same issue, and I fixed that too.
  23. You have two things going on: The size of the physical monitor, which usually corresponds to the resolution, i.e. a 1980x1080 monitor is bigger than a 1280x720 monitor. The size of the pixels. A 3920x2050 monitor will be about the same physical size as a 1920x1080 monitor, but its pixels will be twice as small. The first issue is fairly easy to deal with, just position your UI elements relative to a corner. If you have a display item that is 200x200 pixels, maybe it will be positioned at screenresolution - 220, for example. Another option is to create your UI at whatever default resolution you want, create all widgets, lock them to edges with Widget::SetLayout, and then call Interface::SetSize to slide everything into place. For the second problem, the display scale is the best indication of how big the pixels are. The best way to incorporate this into your UI is to first create your GUI with the assumption that everything is using 100% scaling, and then scale the UI using the display scale. If you use Widget::SetLayout to control which edges each widget is locked to, then everything will scale up perfectly. Additionally, whenever possible you should use Widget::SetIcon instead of Widget::SetPixmap, as icons are resolution-independent images loaded from SVG format.
  24. Updated 1.0.1 Removed PickInfo::GetTexCoords(). Use the texcoords[2] member instead: https://www.ultraengine.com/learn/PickInfo?lang=cpp
×
×
  • Create New...