Jump to content

Collision and terrain holes


Josh
 Share

Go to solution Solved by Josh,

Recommended Posts

This is just a note to myself. Newton heightfield colliders don't support terrain holes and the heightfield needs to be replaced with a custom collider.

Example:

#include "UltraEngine.h"
#include "Components/CameraControls.hpp"

using namespace UltraEngine;

const WString remotepath = "https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets";

int main(int argc, const char* argv[])
{
    //Get the display list
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Terrain Cut", 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->SetFov(70);
    camera->SetPosition(0, 100, -100);
    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(remotepath + "/Terrain/512.r16");
    terrain->SetScale(1, 100, 1);

    //Create base material
    auto ground = CreateMaterial();
    auto diffusemap = LoadTexture(remotepath + "/Materials/Ground/river_small_rocks_diff_4k.dds");
    auto normalmap = LoadTexture(remotepath + "/Materials/Ground/river_small_rocks_nor_gl_4k.dds");
    ground->SetTexture(diffusemap, TEXTURE_DIFFUSE);
    ground->SetTexture(normalmap, TEXTURE_NORMAL);
    terrain->SetMaterial(ground);

    //Camera controls
    camera->AddComponent<CameraControls>();

    shared_ptr<Entity> ball;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->MouseHit(MOUSE_RIGHT))
        {
            ball = CreateSphere(world);
            ball->SetMass(10);
            ball->SetPosition(camera->position);
        }

        if (window->MouseDown(MOUSE_LEFT))
        {
            auto mousepos = window->GetMousePosition();
            auto pickinfo = camera->Pick(framebuffer, mousepos.x, mousepos.y);
            if (pickinfo.success)
            {
                if (pickinfo.entity == terrain)
                {
                    iVec2 pos;
                    pos.x = Round(pickinfo.position.x) + terrain->resolution.x / 2;
                    pos.y = Round(pickinfo.position.z) + terrain->resolution.y / 2;
                    int radius = 10;
                    for (int x = pos.x - radius; x < pos.x + radius; ++x)
                    {
                        for (int y = pos.y - radius; y < pos.y + radius; ++y)
                        {
                            terrain->SetTileHidden(x, y, not window->KeyDown(KEY_CONTROL));
                        }
                    }
                }
            }
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

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

Heightfield colliders only handle flat terrain. There is also a dynamic collider that generates collision dynamically in a function. This is what the Leadwerks Game Engine vegetation system uses, and why collision gets very slow in the vegetation system if you accidentally use a detailed model for the collision shape.

For voxel terrain I would recommend the normal mesh collider.

  • 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

  • Solution

I have it working now.

The depth pre-pass seems to not be considering the discard mask.

Load heightmap seems to not be working with colliision.

But the missing functionailty is added.

#include "UltraEngine.h"
#include "Components/CameraControls.hpp"

using namespace UltraEngine;

const WString remotepath = "https://raw.githubusercontent.com/UltraEngine/Documentation/master/Assets";

int main(int argc, const char* argv[])
{
    //Get the display list
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Terrain Cut", 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->SetFov(70);
    camera->SetPosition(0, 100, -100);
    camera->SetRotation(45, 0, 0);
    camera->SetClearColor(0.125);
    camera->SetDepthPrepass(false);

    //Sunlight
    auto light = CreateDirectionalLight(world);
    light->SetRotation(45, 35, 0);
    light->SetColor(2);

    //Create terrain
    auto terrain = CreateTerrain(world, 512);
    //terrain->LoadHeightmap(remotepath + "/Terrain/512.r16");
    terrain->SetScale(1, 1, 1);

    //Create base material
    auto ground = CreateMaterial();
    auto diffusemap = LoadTexture(remotepath + "/Materials/Ground/river_small_rocks_diff_4k.dds");
    auto normalmap = LoadTexture(remotepath + "/Materials/Ground/river_small_rocks_nor_gl_4k.dds");
    ground->SetTexture(diffusemap, TEXTURE_DIFFUSE);
    ground->SetTexture(normalmap, TEXTURE_NORMAL);
    terrain->SetMaterial(ground);

    //Camera controls
    camera->AddComponent<CameraControls>();

    shared_ptr<Entity> ball;

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->MouseHit(MOUSE_RIGHT))
        {
            ball = CreateSphere(world);
            ball->SetMass(10);
            ball->SetPosition(camera->position);
        }

        if (window->MouseDown(MOUSE_LEFT))
        {
            auto mousepos = window->GetMousePosition();
            auto pickinfo = camera->Pick(framebuffer, mousepos.x, mousepos.y);
            if (pickinfo.success)
            {
                if (pickinfo.entity == terrain)
                {
                    iVec2 pos;
                    pos.x = Round(pickinfo.position.x) + terrain->resolution.x / 2;
                    pos.y = Round(pickinfo.position.z) + terrain->resolution.y / 2;
                    int radius = 10;
                    for (int x = pos.x - radius; x < pos.x + radius; ++x)
                    {
                        for (int y = pos.y - radius; y < pos.y + radius; ++y)
                        {
                            terrain->SetTileHidden(x, y, not window->KeyDown(KEY_CONTROL));
                        }
                    }
                }
            }
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

  • 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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...