Code Monkey home page Code Monkey logo

Comments (35)

Susihiisi avatar Susihiisi commented on May 26, 2024 2

Making collision for whole terrain chunks is quite slow and gets trickier with bigger planets. Fast workaround could be to create collider object which follows the player/enemy/whatmeow, but also sticks to the planet surface and rotates to aproximate slopes as well as it can. Should also ignore all other objects to avoid strange collisions. Creating that for too many objects could of course be performance issue and I don't know what would be the answer for that (bullets for example).

I've used that kind of collider in Unity with Space Graphics Toolkit with realistic sized planets (Earth, Mars) quite successfully. It's not perfect, but it does the job when the planet is big and the slopes aren't too steep or detailed.

//Edit: Space Graphics Toolkit has feature which allows you to stick object to the planet surface and I think it uses heightmap data and noise to do that efficiently. Or whatever data is used to generate the planet. Seems pretty neat as that way you can calculate the position without generating the chunk as they are generated with the same data. It also samples the surrounding (I don't know how) within user specified distance and uses that for rotation, bigger distance gives smoother rotation, but if it's too big you might lose local accuracy. I use that maybe in a bit hacky way by first making the collider object copy the player position and then snappin it to the planet surface, could possibly be made better somehow.

I have no idea how to actually implement any of that, but kind of an idea for a workaround with planetary collisions.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024 1

Hello, thanks for your interest in this project.

I thought about collisions briefly but didn't put too much time into it (yet).

I don't know where the performance hit comes from, did you try to use the Godot profiler to find out what's using up cycles?
When you say inaccurate, did you use the generated LOD (subdivided) terrain meshes to generate matching convex collision shapes? Because if you only used e.g. the first, top level terrain mesh, you'd indeed end up with a very inaccurate collision shape which wouldn't match the subdivided meshes.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024 1

I simply called mesh.create_trimesh_collision() for each generated face on its creation. The problem is that collision shapes contain too many vertices and therefore the collision calculation has to process a lot of data. The solution would be (I guess) to generate a multiple collision shapes for each face, which would allow for hierarchical search of close collision shapes (i.e. ship colliders and only nearby terrain colliders). Godot has a build-in function for that, unfortunately it not accessible via GDScript. Only from engine code.

So the solution would be either implement a wrapper function into the GDScript to create the access to the method from the source. Or, one could create a c++ module and access it directly in the engine code.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024 1

Indeed. Maybe I don't understand the collision system correctly but I did a simple experiment. I set the generation of the collision shape only for the closest planetary face. Then in the editor, I created the ship collision shape using a "single convex collision sibling" made from its mesh and tried a collision of the ship and the planet face. I got barely a single fps. Then again in the editor, I changed it to "multiple convex collision siblings" and I got a dramatic performance gain - if the ship stayed inside the actual terrain face (no generation of the new ones) I got solid 50-60 fps. Therefore, I concluded that the collision detection is only performed between the closest collision shapes (which would make sense). If this is correct then when the faces are generated as multiple collision siblings as well, maybe the performance would increase even more. But I could be wrong of course.

It is possible to use a build-in method for this as I stated in the comment before or maybe it could be done manually based on the generated face vertices that you already have. I also found a hint on the godot forum where they used PhysicsServer to set the faces of the collision shape manually but as I stated in my first comment, I didn't make it work.

But yeah, you can always create the collision shape only for the closest planetary face and leave the global collisions to a single (planet sized) sphere collision shape - that would indeed be sufficient for a planet-planet collision while the player collision with the surface would be accurate enough.

Another way would be to pre-generate both the vertices and collision shapes for each face LOD beforehand and only load those that are currently needed in run-time. That would even speed-up the performance of the whole planet as random generators are notorious performance eaters.

Anyway, I am really looking forward to your planet overhaul! ;)

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024 1

I created a skeleton of the solution using PhysicsServer but as before, it doesn't seem to work. I pushed the current state to the planet_collisions branch so you can have a look if you want. Maybe you'll see something I missed. If I somehow make it work, I'll let you know.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024 1

Brilliant, you made it work! That's great news. I see you set the space, I was going to do that next.
Nevertheless, I found another bug with collisions. When you set the planet scale to a higher value (i.e. 650) you can get through the surface. See the screenshot.
image

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024 1

Right. It's crucial feature. Let's not rush this.

I'm sorry for not helping too much lately. I am really busy these days but as soon I can, I'll participate more often again. Btw look what I found:

https://www.youtube.com/watch?v=KfphtLRoUB0

Maybe we could create another type of planets - Gas giants...

from planet-generator.

Valinakova avatar Valinakova commented on May 26, 2024 1

Just out of curiosity, are you two programmers who work full time? I'm currently learning to program (I'm a beginner). I will try sharing this project with others who may find it interesting who can contribute to it.

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024 1

Hi again guys, just thought id share the progress im doing with my planetary rts game.
image_2024-02-12_105343921

So i got physics working and units wondering around. I ran into a problem with generating the collision shape when the terrain patches were re-generating, the game would crash. So the work around i did was to just have1 LOD (6 patches) for for the entire planet at a detail level of 64 or 128, depending on size. It seems to work great like that, no stutter on mobile devices. If anyone has any insight into that crash it would be great! I can have 350 npcs all going around at around 40fps on mobile devices, i can still tweak more performance out of it.
Also i was wondering how could i go about editing the vertices of the terrain to just raise or lower it at run time. I want the player the ability to change the terrain so that they can create their own maps, or maybe a missel projectile can cause it to deform when hitting the planet. Is that at all feasible? maybe edit the vertArray right before it generates the patch? Not too good with math :(

Thanks again for all the work you put into this project, will def be putting all contributors names in the credits!

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024 1

Regarding the Physics server, i ended up ripping all the physics server stuff from the the code, as i did not understand how it works or even what the physics server is. I imagined it was meant for large scale planets or more complicated stuff and my game is more like a toy. I really only needed the physics to keep the units point down at the planet and once in a while ( every 60 frames more or less depending on the distance to the camera) check if they are floating to push them down to the surface. I added a collision shape to the terrain_patch as a child and the error i get is this:

E 0:00:01:0785 terrain_job.gd:23 @ run(): This function in this node (CollisionShape3D) can only be accessed from either the main thread or a thread group. Use call_deferred() instead.
<C++ Error> Condition "!is_readable_from_caller_thread()" is true. Returning: (Transform3D())
<C++ Source> scene/3d/node_3d.cpp:333 @ get_transform()
terrain_job.gd:23 @ run()
worker_thread.gd:25 @ work()

I have no clue what any of that means. ( Only been using godot for like 2 months, came over from the Libgdx framework)

ill read up on how to pass the flat keyword into the shader.

Thanks!

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

For general, inaccurate collisions, (think planet vs. planet) a sphere shape would suffice.

Well if you create a collision trimesh for every generated chunk, that's a lot of high resolution colliders to check against. If you have a mesh resolution of 100, that's 100*100=10000 vertices or (99^2)*2=19602 triangles to check against for a single terrain patch!

Also, you'll have to disable the colliders of invisible lower LOD meshes or you'll collide with those as well, which might be part of the innaccuracy and performance hit.

So as you can see, a performant terrain collision system has to be thoroughly planned, I've thought about ways to implement it and it's definitely on my list. Help is welcome!

I'll push some big changes in the next days by the way, many parts of the now-addon have been overhauled.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

The engine by default does a broad phase and a narrow phase, it should only check against nearby collision shapes anyway. I'll have to look into it soon.

By the way, heightmap collision shapes just have been implemented for Godot Physics: https://twitter.com/PouleyKetchoup/status/1379603423398535174 Perhaps this could be beneficial? Though the terrain here is a curved mesh, so it won't be that easy.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024

We can definitelly make some iterative experimentation here and try to find the best solution. I've created a planetary_collisions branch as a playground for this purpose.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

So I'm still working on a more robust multithreaded job system for better maintainability and performance. It's kind of functional now, but I'm still debugging some hard to narrow down issues with the threads (multithreading is a beast).
After that I'm going to add physics "back in", probably using the PhysicsServer like we talked about because I don't want to generate physics shapes on the main thread.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024

I was struggling with the collisions lately. Don't have a valid solution the way we discussed it yet. Maybe I'll focus on something else and leave this one on you ;)

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Oh, you actually continued to work on it? Which route did you take, PhysicsServer or physics nodes? I think the latter are not multithreading-friendly at all, I couldn't get it to work reliably using threads in my tests.

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024

Well I created a separate scene with StaticBody and Collision shape and instantiated it for each TerrainPatch. Then I tried to inject the mesh data into CollisionShape but it didn't work and as I was in a separate thread I couldn't debug it directly. I did't even got to the PhysicsServer part. But I have a working example of PhysicsServer. I'll send it to you.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Okay. In the old version of terrain_patch.gd, there's a flag for threads on/off. Yeah, creating physics nodes doesn't seem to work in a thread as far as my tests went, so either it would have to be done in a call_deferred() function or using the PhysicsServer, which may also be faster.
You may also push to the planet_collisions branch if you want, I've locally worked there but then merged all changes into the master branch, so we should be good.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

I had a quick look at the code, it's looking good already, but yeah, apparently there are no collision shapes yet and it throws a lot of physics errors (also had it crash once).

One problem is probably that it's not possible to instantiate and use any physics nodes from another thread as far as my research went. We'll have to use the PhysicsServer for everything, so we wouldn't even instance these nodes but use only the PhysicsServer to add bodies to the physics world.

I also think that we can't use a heightmap collision shape, because the vertices of a terrain patch only look like they're flat, but are in fact warped onto the planet sphere. Also, a heightmap may only be able to face upwards. A trimesh (convex collision shape) should work better, like you did before in your first version of this, it was rudimentary but collisions were there.

By the way, you can either use the uvs array for elevation values, or use the elevations array to pass to the calc_uvs() function :)

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Alright, I built upon your work to create a physics shape (concave polygon shape) and body at runtime using PhysicsServer. After working out the quirks, it's running really stable and performant (apart from the occasional crashes that I described in #9).
Commit b5d0a22.
After the changes proposed in the commit message we could merge planet_collisions into master as for me. I think it's ready after that.

Edit: Oh and also, after you restructured the terrain_patch scene, it was throwing errors when building the mesh about gles3_rasterizer....cpp … surfaces.size() == 0 or something like that. Either way it looked like a timing issue when instancing the MeshInstance as child node instead of working on the instance itself. I don't really know why that happens, only found a few closed Godot issues regarding similar timing issues. So I reverted to the way it was before again.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Now that you mention it, I'm not quite sure whether setting the space is actually needed, I didn't test without it yet.
Yes, I also got stuck below terrain once when I flew at really high speeds at the usual planet scale (200?), it somehow glitched through the terrain. Multiple things could be the issue here:

  1. the scale of the ship etc. is too small. I'm planning on fixing the scaling soon, everything is extremely tiny right now. Scale should be allowed to be a lot bigger, but the current atmosphere shader doesn't play nicely with that, and the lack of 32bit floating point precision will also become noticeable sooner
  2. CCD (continuous collision detection) doesn't work reliably, there are a few Godot issues about that. Would be noticeable at higher speeds (11km/s, 😄)
  3. the collision margin is too low and may fuel into 1. or 2.
  4. there may be an issue with the collision vertices of the concave polygon shapes (unlikely)

For 1. it may help to just limit the speed at low altitudes / when close to the planet, which makes sense anyway.


Two other pending things are:

  • a toggle for collisions from code (globally) and per planet (planet settings)
  • investigating and fixing performance issues at small planets. The profiler showed that _physics_process of the ship.gd becomes incredibly expensive when colliding against several small, dense meshes, up to 40ms per frame

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Okay, I implemented the collision toggles and merged planet_collisions back into master for better maintainability. But I'll leave the branch still to have a space for experiments.

Actually, I reverted the merge because performance is not yet stable, also the multithreading crashes from #9 will have to be solved first, then we can properly take care of making physics better.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Yes. In the latest commits I was able to fix the crashes that occured before, though I'm not quite sure how to best continue with physics, because these complex trimesh collision shapes tend to really tank performance. Perhaps scaling the planets up to a reasonable level (e.g. 1 GD unit = 1km given the single precision floats) will remediate some of the issues as colliders get less dense.
I started to work on that (scaling) first in another branch for now.

I'm sorry for not helping too much lately. I am really busy these days but as soon I can, I'll participate more often again.

Hey that's not a problem at all, I'm not expecting anything but am happy about any help.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Just out of curiosity, are you two programmers who work full time? I'm currently learning to program (I'm a beginner). I will try sharing this project with others who may find it interesting who can contribute to it.

I work full time, but I'm not a programmer by definition, altough I do it a lot for work.

Thanks for sharing the project, that's great!

from planet-generator.

creative-brain avatar creative-brain commented on May 26, 2024

Just out of curiosity, are you two programmers who work full time? I'm currently learning to program (I'm a beginner). I will try sharing this project with others who may find it interesting who can contribute to it.

I also work full time and apart from other things I also do some programming.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

So I found that PhysicsServer is not completely multithreading-friendly in 3.x, but at least that should be fixed in 4.0: godotengine/godot#45852
In the meantime I'm using a Mutex in terrain_patch.gd to create physics shapes and bodies from multiple threads, which is of course slower but at least it doesn't throw random errors and doesn't crash.

The glitching (collider jumps below terrain trimesh) was also fixed by a higher collision margin, by the way.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Collisions need to be looked at again on 4.x. For now, collisions are disabled on the dev branch.

I'll leave this issue open for that as well.

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024

IMG-20231206-WA0000
Hi guys, i modified the engine so that i can get small SPORE like planets. Not intrested in the realistic sizes. So i wanted to know if there was a a way i can get collisions to work with a small planet. My game will use planets with radius size of 24 max and moons of 12. I read the engine has physics and collisions, how would i get this to work so that i can have my character walk on the planet? (no spaceships in my game). Also, i set it up so that the planets only have two LODs, the 6 patch and the one after it, no more. at a resolution of 32 to hopefully make it easier on the collision mesh. Any ideas?

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Hey, nice to see that you are finding the library useful.

in theory, setting the flag:

const COLLISIONS_ENABLED := false # Whether planets generate collision shapes.
activates collision meshes to be built and pushed to the physics server. This caused issues with instability and crashes in Godot 3, however.

In practice, I haven't tested this yet on Godot 4.

What did you try so far?

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024

Hey, nice to see that you are finding the library useful.

in theory, setting the flag:

const COLLISIONS_ENABLED := false # Whether planets generate collision shapes.

activates collision meshes to be built and pushed to the physics server. This caused issues with instability and crashes in Godot 3, however.
In practice, I haven't tested this yet on Godot 4.

What did you try so far?

Hi, thanks for taking the time to reply.
I did try enabling the collisions and physics thru that script you mentioned. However any rigidbody3D I placed does not get pulled towards the planet , and even if the rigidbody3d collided with the planet it just falls through. Am I missing something? I added an Area3D and set point gravity to have things pulled towards the area. However I'm not sure that's the right move here since your engine probably requires its own implementation of gravity that is used with your collision system.
The game I'm making is an rts type game where units will move along the planet and fight , so it pro a ly does not need to be so accurate if that helps.
I must have spent like 5 hours trying to get the collisions to work. Any help is welcomed.

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024

Also, how can i make the normals on the mesh flat shaded ? like a low poly style type game. Thanks again, great project!

from planet-generator.

VecterraSoft avatar VecterraSoft commented on May 26, 2024

Okay so I managed to fix my physics collisions by just adding my own static collision shape to the terrain patch scene by pulling the mesh data from the terrain patch mesharray after it generates. It works flawlessly now. Still would appreciate a how to for flat shaded normals. Thanks guys for making this project. It's by far the least bloated of the planet engines and it runs the fastest on mobile devices.

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

Great to hear you could make collisions work on Godot 4.

If you experience crashes you might want to try performing all operations on the PhysicsServer on the main Godot thread instead of another thread:


I thought the servers were thread safe but apparently they aren't yet. I ran into similar issues with crashes on Godot 3.x.

Also, how can i make the normals on the mesh flat shaded ? like a low poly style type game. Thanks again, great project!

Apparently Godot supports a flat shading mode when passing flat into the shader.

The normals are calculated here. Each vertex normal is just the average of the edges leading to it:

from planet-generator.

Hoimar avatar Hoimar commented on May 26, 2024

I have no clue what any of that means. ( Only been using godot for like 2 months, came over from the Libgdx framework)

@VecterraSoft this means that the get_transform() function is being called from a thread which isn't allowed to read it just like that. Probably a change inside Godot's threading which affects how scripts can use threads while interacting with nodes, is my guess from this and the Godot 4 changelogs.

I'll have to look at it in detail, but I'm not sure if I can reproduce it because I'd need a MVCE from you for that.

from planet-generator.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.