Jump to content

Ultra Engine testing


Josh
 Share

Recommended Posts

Not sure if this is a bug or I'm not using it right - should SetTorque() on a kinematic joint disable all rotation?  I just want to position the joint and no matter what happens to it, have it never rotate.  Here moving the joint makes it rotate all over the place.

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    auto plugin = LoadPlugin("Plugins/LELegacy.dll");

    //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();

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

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);
    camera->SetFov(70);


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

    auto floor = CreateBox(world, 100, 0.1, 100);
    floor->SetPosition(0, -1, 0);


    auto hub_pivot = CreateBox(world, 0.25f);
    hub_pivot->SetCollider(nullptr);
    hub_pivot->SetMass(1.0f);
    hub_pivot->SetColor(0, 1, 0);

    auto slider_pivot = CreateBox(world, 0.25f);
    slider_pivot->SetMass(1.0f);
    slider_pivot->SetColor(0, 0, 1);

    auto cam_pivot = CreatePivot(world);
    cam_pivot->SetParent(slider_pivot);
    cam_pivot->SetPosition(0.0f, 2.5f, 0.0f, true);

    camera->SetParent(cam_pivot);
    camera->SetPosition(0.0f, 1.8f, -5.0f, true);
    camera->SetRotation(25.0f, 0.0f, 0.0f);

    auto k = CreateKinematicJoint(Vec3(0, 0, 0), hub_pivot);
    k->SetMaxTorque(0.0f);
    auto s = CreateSliderJoint(Vec3(0, 0, 0), Vec3(0, 1, 0), hub_pivot, slider_pivot);

    Vec3 mousepos;
    float lookspeed = 0.1f;
    float looksmoothing = 0.5f;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        auto _displaySize = window->GetSize();
        float cx = Round((float)_displaySize.x / 2.0f);
        float cy = Round((float)_displaySize.y / 2.0f);

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

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

        float angle = cam_pivot->GetRotation().y;
        Vec3 pos = hub_pivot->GetPosition(true);
        Vec3 up = Vec3(0.0f, 1.0f, 0.0f);
        Vec3 direction = Vec3(Sin(angle), 0, Cos(angle));
        Vec3 strafe = direction.Cross(up).Normalize();

        if (window->KeyDown(KEY_W)) { k->SetPose(pos + direction, Vec3()); }
        if (window->KeyDown(KEY_S)) { k->SetPose(pos - direction, Vec3()); }
        if (window->KeyDown(KEY_A)) { k->SetPose(pos + strafe, Vec3()); }
        if (window->KeyDown(KEY_D)) { k->SetPose(pos - strafe, Vec3()); }

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

 

Link to comment
Share on other sites

SetMaxTorque controls the maximum force the joint can use to control the rotation of the entity, so you would want that to be a big number. If the max torque is zero the joint will rotate freely.

  • 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

How did you retrieve the framerate in your demos? I've made a simple application to load Cyclone maps and world->renderstats.framerate returns 0. 

Somethings I've encountered.

  • Coming from Leadwerks, I was using ui->GetBase() instead of ui->root.
  • DebugLog() does not compile under release for some reason. I would just #ifdef out the printing within the function.
  • Having an issue resizing an interface in 3D when the window goes to fullscreen.

Here's my code. It has a lot of custom functions but it gives you an idea of what I'm trying to do.

#include "UltraEngine.h"
#include "ComponentSystem.h"

#include "Core/command.h"
#include "GameWindow.h"

using namespace UltraEngine;
#define DEFAULT_MAP "Maps/lvl7.map"

int main(int argc, const char* argv[])
{
    Core::ParseCommandLine(argc, argv);

    //auto plugin = LoadPlugin("Plugins/LELegacy.dll");

    //Create a world
    auto world = CreateWorld();

    //Get the displays
    auto displays = GetDisplays();

    auto settings = GameWindowSettings
    {
        0,
        0,
        0,
        1280,
        720,
        WINDOW_CENTER | WINDOW_TITLEBAR
    };

    // Create the window. 
    // This will also create a framebuffer.
    auto window = CreateGameWindow("Ultra Preview", settings);

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

    auto actor = CreateActor(camera);
    actor->AddComponent<CameraControls>();

    // HUD
    auto viewport_size = window->GetFramebuffer()->size;
    auto hudcamera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    hudcamera->SetClearMode(CLEAR_DEPTH);
    hudcamera->SetPosition(viewport_size.x / 2, viewport_size.y / 2);
    hudcamera->SetRenderLayers(RENDERLAYER_1);

    //Create user interface
    auto ui = CreateInterface(world, LoadFont("Fonts/arial.ttf"), viewport_size);
    auto background = ui->background;
    background->SetColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
    //background->SetLayout(1, 0, 1, 1);
    ui->SetRenderLayers(RENDERLAYER_1);

    //Create widget
    iVec2 sz = ui->root->ClientSize();
    auto fpscounter = CreateLabel("FPS: ", 2, 2, 100, 12, ui->root);

    WString map = Core::GetArgument("map");
    Print(map);
    if (map.empty()) map = DEFAULT_MAP;

    auto scene = LoadScene(world, map);
    if (scene == NULL)
    {
        Print("Failed to load scene!");
        camera->SetClearColor(0.125);

        //Create a light
        auto light = CreateBoxLight(world);
        light->SetRotation(35, 45, 0);
        light->SetRange(-10, 10);
        auto box = CreateBox(world);
        box->SetColor(0,0,1);
    }

    window->Activate();

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_END) == false)
    {
        // Toggle between modes.
        if (window->KeyHit(KEY_SPACE))
        {
            static bool fullscreen = false;
            fullscreen = !fullscreen;
            window->SetNativeFullscreen(fullscreen);

            // This is broke, IDK.
            viewport_size = window->GetFramebuffer()->size;
            hudcamera->SetClearMode(CLEAR_DEPTH);
            hudcamera->SetPosition(viewport_size.x / 2, viewport_size.y / 2);
            hudcamera->SetRenderLayers(RENDERLAYER_1);

            ui->Redraw(0, 0, window->GetFramebuffer()->size.x, window->GetFramebuffer()->size.y);
            ui->UpdateLayout();
            ui->root->Redraw();
        }

        world->Update();

        //const int fps = world->renderstats.framerate;
        //if (fpscounter) fpscounter->SetText("FPS: " + String(fps));

        // Since the framebuffer is destoryed and rebuilt between changing modes, 
        // We need to tell the window to manage our world's updating
        window->Render(world);
    }
    return 0;
}

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

Just a sidenote: 

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using UltraEngine;
using static UltraEngine.Functions;
using Object = UltraEngine.Object;

namespace UltraAppKitCore.Sample
{
   
    class Program
    {
        static void Main(string[] args)
        {
            //Get the displays
            var displays = GetDisplays();

            //Create a window
            var window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WindowStyles.WINDOW_CENTER | WindowStyles.WINDOW_TITLEBAR);

            //Create a world
            var world = CreateWorld();

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

            //Create a camera
            var camera = CreateCamera(world);
            camera.SetClearColor(0.125f, 0.125f,0.125f);
            camera.SetFov(70f);


            //Create a light
            var light = CreateDirectionalLight(world);
            light.SetRotation(35f, 45f, 0f);
            light.SetRange(-10, 10);           

            //Main loop
            while (window.Closed() == false && window.KeyDown(KeyCode.KEY_ESCAPE) == false)
            {             
                world.Update();
                world.Render(framebuffer);
            }
        }
    }

}

this is a sample which actually runs in c# and .net core :)

  • Windows 10 Pro 64-Bit-Version
  • NVIDIA Geforce 1080 TI
Link to comment
Share on other sites

8 minutes ago, klepto2 said:

this is a sample which actually runs in c# and .net core :)

I know two million people who are going to be very happy to have that available.

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

3 hours ago, SpiderPig said:

Are you still planning on making the character controller work with different gravity directions?

Yes but not immediately

  • 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

I'm going to do the final shader adjustments last because...I don't know why, I just feel it is right.

I would really like to test on an AMD 480/580 but no one will help me. 😪

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

Looking forward to the official release!

 

I'm taking a look at the LOD system - it all works well - just wanted to ask if instead of having several GLTF files for each LOD stage and letting the application compile it into one model at run-time, can I export one GLTF file with the LOD's as different meshes?  If yes - will it still work if I have 2 meshes at each LOD?  Like a tree - one mesh for the trunk and another for the leaves?

Link to comment
Share on other sites

12 minutes ago, SpiderPig said:

Looking forward to the official release!

I'm taking a look at the LOD system - it all works well - just wanted to ask if instead of having several GLTF files for each LOD stage and letting the application compile it into one model at run-time, can I export one GLTF file with the LOD's as different meshes?  If yes - will it still work if I have 2 meshes at each LOD?  Like a tree - one mesh for the trunk and another for the leaves?

There is an Lod glTF extension from Microsoft but I have not implemented it:
https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/MSFT_lod

I don't know if it's really a great idea because no 3D modeling package will support it. If you merge Lod levels into a single glTF file, you are creating a one-way conversion step that can't be pulled back into a modeling program for editing, and avoiding that was one of the major reasons to use glTF in the first place.

  • 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

Have a small issue with my tree after setting the environment maps...

 

TreeIssue.thumb.png.c21ad91ac06272d36c9446ccab793696.png

 

#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 world
    auto world = CreateWorld();
    world->RecordStats();

    //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, -3);

    auto font = LoadFont("Fonts/arial.ttf");
    auto ui = CreateInterface(world, font, framebuffer->size);
    ui->SetRenderLayers(RENDERLAYER_1);
    ui->root->SetColor(0, 0, 0, 0);

    auto fps = CreateLabel("FPS : 0", 10, 10, 150, 30, ui->root);

    auto ui_cam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    ui_cam->SetPosition(framebuffer->size.x / 2, framebuffer->size.y / 2, 0);
    ui_cam->SetRenderLayers(RENDERLAYER_1);
    ui_cam->SetClearMode(CLEAR_DEPTH);

    auto d = LoadTexture("Materials\\Environment\\Storm\\diffuse.dds");
    auto s= LoadTexture("Materials\\Environment\\Storm\\specular.dds");
    world->SetEnvironmentMap(s, ENVIRONMENTMAP_BACKGROUND);
    world->SetEnvironmentMap(s, ENVIRONMENTMAP_SPECULAR);
    world->SetEnvironmentMap(d, ENVIRONMENTMAP_DIFFUSE);

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

    //Create a box
    auto box = CreateBox(world, 1000.0f, 0.1f, 1000.0f);

    auto tree = LoadModel(world, "Foliage\\PineLarge_001.gltf");

    Vec3 mousepos;
    float lookspeed = 0.1f;
    float looksmoothing = 0.5f;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        auto _displaySize = window->GetSize();
        float cx = Round((float)_displaySize.x / 2.0f);
        float cy = Round((float)_displaySize.y / 2.0f);

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

        auto camrot = camera->GetRotation();
        camrot.x += dy;
        camrot.y += dx;
        camera->SetRotation(camrot);
        mousepos = mouse_position;

        if (window->KeyDown(KEY_W)) { camera->Move(0.0f, 0.0f, 1.0f); }
        if (window->KeyDown(KEY_S)) { camera->Move(0.0f, 0.0f, -1.0f); }
        if (window->KeyDown(KEY_A)) { camera->Move(-1.0f, 0.0f, 0.0f); }
        if (window->KeyDown(KEY_D)) { camera->Move(1.0f, 0.0f, 0.0f); }

        fps->SetText("FPS : " + String(world->renderstats.framerate));

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

 

PineTree.zip

Link to comment
Share on other sites

Repository for free assets created. There are some ready to use environment maps:
https://github.com/UltraEngine/Assets

You have the IBL sampler application in the Tools folder now. The way I made these is by dragging an HDR image from here onto run.bat:
https://github.com/KhronosGroup/glTF-Sample-Environments

And then I run this code to convert the KTX2 files into a BC8H DDS:
https://www.ultraengine.com/community/blogs/entry/2780-building-a-single-file-4k-hdr-skybox-with-bc6-compression/?tab=comments#comment-14747

  • 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

Not sure if I fully understand this or something is amiss.

Is World::Pick() using the collision system?  If so an object with a null collider still gets picked.

Is the collisiontype argument to pick only objects exclusively with that type or is this type omitted from the pick?

There is a usecollider argument in the docs but it's not there to use.

The use of collisiontype gives me mixed results, I've commented in the code what it does.

 

#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 world
    auto world = CreateWorld();

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

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

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

    auto floor = CreateBox(world, 100.0f, 0.1f, 100.0f);
    floor->SetCollisionType(COLLISION_SCENE);

    //Create a box
    auto box = CreateBox(world);
    box->SetCollisionType(COLLISION_PROP);
    box->SetColor(0,0,1);

    auto box2 = CreateBox(world, 0.25f);
    box2->SetCollider(nullptr);//Setting just this dosnt stop detection
    box2->SetCollisionType(-1);//This will
    box2->SetPosition(0, 2, 0);

    auto sphere = CreateSphere(world, 0.1f);
    sphere->SetCollider(nullptr);
    sphere->SetCollisionType(-1);
    sphere->SetColor(1, 0, 0);

    //Main loop
    auto stage = 0;
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        auto box_pos = box2->GetPosition(true);
        switch (stage) {
        case 0:
            if (box_pos.x > -2 && stage == 0) { box2->Move(-.01, 0, 0); }
            else { stage = 1; }
            break;
        case 1:
            if (box_pos.x < 2 && stage == 1) { box2->Move(.01, 0, 0); }
            else { stage = 0; }
            break;
        }

        Vec3 start_pos = box2->GetPosition(true);
        Vec3 end_pos = start_pos - Vec3(0.0f, 10.0f, 0.0f);

        auto pick_info = world->Pick(start_pos, end_pos, 0.0f, true, COLLISION_PROP);//Detects both floor and box - should only be box?
       // auto pick_info = world->Pick(start_pos, end_pos, 0.0f, true, COLLISION_SCENE);//Detects only box - should only be floor?
        if (pick_info.success) {
            sphere->SetPosition(pick_info.position);
        }
        sphere->SetHidden(!pick_info.success);

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

 

Link to comment
Share on other sites

Update

Fixed this issue: https://www.ultraengine.com/community/topic/61132-ultra-engine-testing/page/26/#comment-297777

@klepto2Quads are probably better for water. You can create a quad mesh by supplying MESH_QUADS in the last parameter.

Basically for any geometry that can use quads, that will always tessellate better than triangles.

 

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

6 hours ago, SpiderPig said:

Is World::Pick() using the collision system?  If so an object with a null collider still gets picked.

Is the collisiontype argument to pick only objects exclusively with that type or is this type omitted from the pick?

There is a usecollider argument in the docs but it's not there to use.

The use of collisiontype gives me mixed results, I've commented in the code what it does.

1. No, it performs a raycast test on the mesh geometry.

2. The collision type follows the rules of the collision responses: https://www.ultraengine.com/learn/World_SetCollisionResponse?lang=cpp

3.  There is a feature partially implemented that would perform a raycast on the physics collider instead of the visual geometry. It's not accessible so I should fix the docs.

4. See #2.

It would be possible for me to add a callback function to handle the filtering yourself. That might be a better approach for Ultra. It would be something like this:

bool PickFilter(shared_ptr<Entity> entity, shared_ptr<Object> extra)
{
   //This makes it so only a terrain can be picked
   if (entity->As<Terrain>()) return true; else return false;
}

 

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

2 hours ago, Josh said:

3.  There is a feature partially implemented that would perform a raycast on the physics collider instead of the visual geometry. It's not accessible so I should fix the docs.

I would like to choose between the two if possible.

2 hours ago, Josh said:

It would be possible for me to add a callback function to handle the filtering yourself. That might be a better approach for Ultra. It would be something like this:

bool PickFilter(shared_ptr<Entity> entity, shared_ptr<Object> extra)
{
   //This makes it so only a terrain can be picked
   if (entity->As<Terrain>()) return true; else return false;
}

I think this is a good idea.

Link to comment
Share on other sites

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

×
×
  • Create New...