Jump to content

Slastraf

Developers
  • Posts

    705
  • Joined

  • Last visited

Posts posted by Slastraf

  1. 1 minute ago, Rick said:

    Can you elaborate on the same output every time? Is each terrain tile the same? If not how would very terrain tile always be the same between runs if you can have infinite  amount of them?

    All random number generators only produce pseudo random numbers and you can use it to your advantage because if you initialize it with a seed like "123" it will always generate the same infinite numbers for that seed. For the terrain height generation I use perlin noise which is like a controlled 2d fractal / noise. I used a cpp library for perlin noise as a height map to set the vertices height of the tiles. 
    It can never be the same if the seed is always different for each new playtrough. But if you you use the same seed you can have the exact same world as someone else.

  2. Yes I can share it, but with the seed you don't need to store it in a db because it will generate the same output every time.
    I will put it on in a bit. I want to add texture generation and make it more readable / stable. Its missing physics and textures basically. The player is moved by raycasts.

  3. 6 minutes ago, Rick said:

    @Slastraf I would imagine you're recycling 9 chunks? If you make 8 copies of the 1 terrain model then as the player moves around I would think you could just reuse the ones the player is furthest away from so then you only need to call Copy() during initialization of your game right?

    That would be doable if copy takes a long time. For now the Idea is to copy it and iterate over vertices for every new chunk and hide out of bound ones.

  4. I Instantiate a loaded model like this 
     

    worldGenerator->terrainChunk = Model::Load("Models/terrain_Plane.mdl");
    
    ...
    
    c->chunkModel = (Model*)terrainChunk->Instance();

    then I applied some previously tested code on the surface of the model like this:
     

    
                Surface* surface = c->chunkModel->GetSurface(0);
                for(int i = 0; i<surface->CountVertices(); i++)
                {
                    Vec3 xy = surface->GetVertexPosition(i);
                    float height = (rand()%(3));
                    if(i==surface->CountVertices()*0.5) {
                        height = -100*(rand()%(3));
                        cout<<"Offset height:"<<height;
                    }
                    if(i==0)cout<<"height at: "<<height<<endl;
                    surface->SetVertexPosition(i, xy+Vec3(0,height*.1,0));
                }
                surface->Update();
                c->chunkModel->UpdateAABB(Entity::LocalAABB | Entity::GlobalAABB);

    For every vertex, I set a randomly generated position. This is simplified to show the issue.
    All the generated model chunks are the same. A good guess would be that LE copies an already Instantiated model over, and overwrites all changes of the current one to all previous ones, or somehow ignores changes otherwise.
    I put a screnshot of the console and two images showing duplicate chunks. There are 9 chunks and each of them looks the same. How to fix this behaviour ?

    Theomenofpenumbra Screenshot 2021.04.12 - 13.18.27.97.png

    Theomenofpenumbra Screenshot 2021.04.12 - 13.18.21.34.png

    Bild_2021-04-12_131939.png

  5. Most .mdl files have a hierarchy similar to this

    STATIC_MESH (< no surface)
    - OBJECT THING (< with surface)

    The surface count in the latter case will be zero, even if there is a surface in the OBJECT THING
    The workaround is to collapse the whole thing in the model editor.
    It would be nice if getsurface will check the first child for surface too if the top level doesn't have one because it is exported like this in most modeling software.

  6. Just now, Rick said:

    What is actually causing the little pause? Is it the creation of the flat mesh itself? Is it manipulating the terrain mesh it 1 iteration? Off the top of my head I would copy the flat terrain mesh, which should be instant and I don't think cause a pause, and then as you're manipulating the vertices of the terrain that would have to be done over multiple frames so there is no noticeable pause. I think I did something like this back in the day and it was easiest to do in lua because of coroutines running over multiple frames. I was able to manipulate a handful of terrain vertices every loop before I'd yield out of the coroutine to give cycles back to the game so it didn't cause a noticeable pause.

    I generate new vertices, traingles for every new mesh completely new. Agreeably this takes long. To copy it over and iterate all verts to put them on the generated position could be much faster. The chunks don't have that many verts so it takes less than a few frames. How to access mesh information ? 

  7. I have coded a basic terrain generator which takes a perlin noise and builds a mesh from that.
    The problem is this is an expensive task for real time. So I put the whole function which calculates the chunks in a second thread which is handled in the game loop.
    This has not helped much with the performance, as I am using Leadwerks functions inside the thread which still accesses the game world and makes it freeze for a split second. Is there any way to calculate the mesh in a different thread and then "load" it into the world ?
    An explanatory video below.
    Thanks

  8. 2 minutes ago, Josh said:

    Your code above is creating 1000 new model entities. I would expect that to be a fairly slow process.

    That pointed me in the right direction. I made everything into one model, it still lagged, then I also made only one surface and then I got acceptable performance. Still it should not lag in the first place. The code looks like this and now I can proceed. 
     

    void generateTest(){
    
     //   std::random_device rd; 
     //   std::uint32_t seed = rd();
    	//const siv::PerlinNoise perlin(seed);
        Surface* surface = NULL;
        Model* model = NULL;
        model = Model::Create();
        model->SetColor(1.0, 0.0, 1.0);
        surface = model->AddSurface(); 
        for(int i = 0; i<1000; i++)
        {
                surface->AddVertex(0.5, 0, 0.5, 0, 0, 1);
                surface->AddVertex(0.5, 0, -0.5, 0, 0, 1);
                surface->AddVertex(-0.5, 0, 0.5, 0, 0, 1);
                surface->AddVertex(-0.5, 0, -0.5, 0, 0, 1);
                surface->AddTriangle(0, 1, 2);
                surface->AddTriangle(1, 2, 3);
                surface->Update();  
                model->UpdateAABB(Entity::LocalAABB | Entity::GlobalAABB);
        }
    }

     

  9. void generateTest(){
        //const siv::PerlinNoise perlin(seed);
        Surface* surface = NULL;
        Model* model = NULL;
        for(int i = 0; i<1000; i++)
        {
                model = Model::Create();
                model->SetColor(1.0, 0.0, 1.0);
                surface = model->AddSurface(); 
                surface->AddVertex(0.5, 0, 0.5, 0, 0, 1);
                surface->AddVertex(0.5, 0, -0.5, 0, 0, 1);
                surface->AddVertex(-0.5, 0, 0.5, 0, 0, 1);
                surface->AddVertex(-0.5, 0, -0.5, 0, 0, 1);
                surface->AddTriangle(0, 1, 2);
                surface->AddTriangle(1, 2, 3);
                surface->Update();  
                model->UpdateAABB(Entity::LocalAABB | Entity::GlobalAABB);
        }
    }

    Hello
     

    after I wanted to make a mesh generation algorithm I found out that I get a lot of lag when trying to have a small amount of vertex (<10k) in the scene
    If you run the test example above, it will make the game run at 2 fps or less.
    It does not max out my ram / gpu at all. I guess it has to do with memory leaks because I did not delete surface and model pointer.
    Then I tried to do the latter but it made different errors.

  10. 3 minutes ago, Optimus Josh said:

    I created an example that shows the error you described, and I am working on fixing it, and now you are describing another situation you want me to guess and try to create before I have fixed the thing you were reporting? You are dancing around too much. I need a piece of code I can copy and paste.

    Sorry to bother so much, yes the original post was about selection Nodes, but my post from 19 hours ago was to reset the whole tree (and it worked prior but not anymore). Regardless, both things need to work. There shou.ld be ->SetParent(NULL) to remove 1 item and also tree->root->SetParent(NULL) or an equivalent tree->root->ClearNodes() (exists but throws error currently) which resets the whole tree.

  11. 11 minutes ago, Optimus Josh said:

    Step one is to produce the bug. Now I have done that and we have something we can both run:

    
    
    #include "pch.h"
    
    using namespace UltraEngine;
    
    int main(int argc, const char* argv[])
    {
        //Get the displays
        auto displays = ListDisplays();
    
        //Create a window
        auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0]);
    
        //Create User Interface
        auto ui = CreateInterface(window);
    
        //Create widget
        auto sz = ui->root->ClientSize();
        auto treeview = CreateTreeView(10, 10, sz.x - 20, sz.y - 20, ui->root);
    
        auto node = treeview->root->AddNode("Node 1");
        node->AddNode("Subnode 1");
        node->AddNode("Subnode 2");
        node->AddNode("Subnode 3");
    
        node = treeview->root->AddNode("Node 2");
        node->AddNode("Subnode 1");
        node->AddNode("Subnode 2");
        node->AddNode("Subnode 3");
    
        node = treeview->root->AddNode("Node 3");
        node->AddNode("Subnode 1");
        node->AddNode("Subnode 2");
        node->AddNode("Subnode 3");
    
        while (true)
        {
            const auto& event = WaitEvent();
            switch (event.id)
            {
            case EVENT_WINDOWCLOSE:
                return 0;
                break;
            case EVENT_WIDGETACTION:
                {
                    node = event.extra->As<TreeViewNode>();
                    node->SetParent(NULL);
                }
                break;
            }
        }
        return 0;
    }

     

    That is good and I have implemented a similar thing, but what if you want to remove all nodes from the tree ?
    You could select an item and delete it, but in an other case I want to reset the whole tree. For example you have 10 different users and for each user there is a list of items and you want the tree to display all items of the selected user. This requires for the entire tree to refresh and rebuild. This functionality does not work anymore because a few days ago you could take the node which you iterated the tree with (like my example above) and set its parent to null and the tree would hide. This does not work anymore. Can you provide an example for reseting the tree ?

×
×
  • Create New...