Comments (35)
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.
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.
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.
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.
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.
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.
from planet-generator.
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.
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.
Hi again guys, just thought id share the progress im doing with my planetary rts game.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
- 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
- CCD (continuous collision detection) doesn't work reliably, there are a few Godot issues about that. Would be noticeable at higher speeds (11km/s, 😄)
- the collision margin is too low and may fuel into 1. or 2.
- 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 theship.gd
becomes incredibly expensive when colliding against several small, dense meshes, up to 40ms per frame
from planet-generator.
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.
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.
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.
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.
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.
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.
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.
Hey, nice to see that you are finding the library useful.
in theory, setting the flag:
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.
Hey, nice to see that you are finding the library useful.
in theory, setting the flag:
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.
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.
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.
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.
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)
- Atmosphere with clouds HOT 5
- Add Bilboard mode to the Sun corona HOT 1
- Doesn't work on HTML5 HOT 4
- Generating planet(s) frequent crashes the Godot Editor or the application
- Planet's mustn't move
- Save the patches in cache? HOT 2
- UV coordinates between different TerrainFace chunks/tiles don't match up HOT 2
- Correctly calculate TerrainFace seams
- Applying custom visual shader to the planet? HOT 5
- Occasional multithreading related crashes (especially benchmark scene) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from planet-generator.