- Home /
Deleting one triangle out of mesh? Cut hole in mesh in runtime?
I am experimenting with terrain generation. I am using Unity's built-in plane, and using randomized variables to deform the position of each vertex in the plane.
Sometimes, the mesh will end up folded inside itself, in such a way that there are some triangles whose back side face the player. Since you can't see these triangles, and you can pass through them, sometimes you wind up getting stuck inside the mesh, unable to get out.
Some solutions I have found would involve turning off backface culling (then the player would at least be able to see these triangles), but this would mean a big performance hit and still wouldn't solve getting stuck.
One solution I have thought of is to allow the user to break through, by deleting a triangle so that he/she can get out of the cave in which they are stuck.
The question: Is it possible to delete a single triangle from a mesh during runtime, so that there is a hole in the mesh through which the player can escape?
Edit: Strange - last night there was a comment on this, but coming back to reread it, it's now gone. I wonder why that poster deleted his response?
@Aeschylus , you are making the whole issue extremely hard on yourself.
WHEN YOU $$anonymous$$OVE VERTICES, YOU CAN ONLY $$anonymous$$OVE THE$$anonymous$$ A 'REASONABLE A$$anonymous$$OUNT.
It's just that simple. $$anonymous$$ove on ! Heh !
Forget the totally irrelevant issues about culling, deleting etc.
Now --------- if you do want to "$$anonymous$$A$$anonymous$$E EXTRE$$anonymous$$E $$anonymous$$OVES IN VERTICES". The actual thing for you to look in to is that, you need to increase the triangle density locally at that region.
If you are totally in to the issue - which is awesome! - that's what you need to learn how to do. It's a great field, enjoy!!!
Answer by aldonaletto · Jun 18, 2012 at 09:33 PM
I think this is the wrong solution, and may cause more problems. It would be better to avoid this folding back thing - you could for instance vary only the vertex Y coordinate, and/or modify the X and Z coordinates at most 50% of the distance between vertices.
Anyway, you can delete triangles from the mesh to make holes: get the triangles from the mesh in an array, delete the ones you want and assign the array back to the mesh triangles - but don't delete vertices! some of them may be shared by other triangles.
There's this interesting answer from @Bunny83 that removes all triangles whose normals are below some angle in a mesh collider - maybe it can show you some useful mesh tricks.
Thanks for the response. For sure, by limiting the variance of each vertex, I wouldn't have this problem, but I'd also lose a lot of the interesting features that this creates. I've got one area that only varies the Y coordinate, but as soon as I started varying the X coordinate it made the terrains an order of magnitude more complex and interesting.
I guess I'm trying to have my cake and eat it, too. It may end up not being feasible, but maybe there is a way to make it all work.
Answer by Wolfram · Jun 18, 2012 at 09:36 PM
Backface culling is no performance hit if most of your faces are frontfacing anyway. Also, you would only give your "terrain" the shader with culling set to off, so for all your other models, backface culling is still in effect.
Yes, in theory you could remove a single triangle from a mesh's triangle list. However, I don't think Unity gives you any convenience functions to determine a very specific triangle within a mesh. Physics.Raycast only gives you the object (and hence the whole mesh) that was hit, not a specific triangle. So in the worst case you would have to re-implement raycasting for triangles (check any raytracing tutorial on how to do that) to walk through the triangle list of your mesh, and then remove it from the list.
But maybe the better approach would be to constrain your deformation parameters somehow, so that backfacing triangles don't occur in the first place?
EDIT: Actually, there is a convenience function to find the corresponding triangle index of a RaycastHit, if the object is a MeshCollider: RaycastHit.triangleIndex. With this, your original approach should be easy to implement. Thanks for the pointer, @Fattie.
Am I right in thinking that backface culling would only change the rendering of faces, and not collision? As I understand it, the built-in plane has a collider that only works from one direction, which is part of my problem. I'm thinking that even if I make/find a shader with backface culling turned off, I'll still be able to pass through the backfacing triangles, but I'll at least be able to see them.
I could be wrong though, as I'm a complete beginner to game design and scripting. Thanks for your comment!
Yes, according to the docs, collisions do not happen with backfacing parts of the $$anonymous$$eshCollider, and changing the shader to a no-culling shader probably won't change that. Unfortunately, I can't think of a quick workaround for you.
One solution would be, to actually make a clone of your mesh, but reverse the point order in your triangles, i.e. create the actual mesh for the backside of your mesh. So if the indices of your triangle array are for example a,b,c, d,e,f, g,h,i change the order to a,c,b, d,f,e, g,i,h and so on.
Then create mesh colliders for both meshes, and get rid of the two-sided shader, which is no longer necessary.
Actually, you don't even need a separate mesh for this, just append the triangle array with the modified order to your regular triangle array. This way, you also need just one $$anonymous$$eshCollider.
Edited the question to include RaycastHit.triangleIndex, which can help you.
Answer by coder8 · Jun 19, 2012 at 08:15 AM
This may be a little more complex than you are looking for but instead of working with a mesh right away you could generate a "point cloud". Each point is at a coordinate like (3,1,5) (3,0,5) etc... To generate interesting shapes and figures look into noise generating algorithms like Perlin Noise. After this use an algorithm like Marching Cubes to connect up all of the vertices. Unity comes with a nice script to generate the noise and the wiki has a marching cube example here Marching Cubes. Those two algorithms should get you on the right track. Hope that helps!
Your suggestion would make me cry when testing it out. BUT I WANT TO SO BADLY.
ouch! a point cloud, Tim, you win the award for "most incredibly awesome advanced technology suggested in response to a beginner question!"
Aeschylus (great nickname BTW!), perhaps you should get in to THIS! do it in th gpu !
http://answers.unity3d.com/questions/267050/vertex-program-max-instructions-limit.html
notice the video i linked to in the comments
for innovative solution, and for recognizing that the OP probably wants something else, ins$$anonymous$$d of trying to fix and workaround his current troubles
Answer by Wolfram · Jun 19, 2012 at 10:10 AM
Another possibility is to use a fractal subdivision algorithm, which has the advantage of creating very realistic terrains, with unlimited detail. See http://www.gameprogrammer.com/fractal.html or elsewhere
Great thinking ! there's a newbie approach :-)
Personally I would get mapping data of the, well, Earth's land surface, and then create an evolutionary algorithm approach that runs for a few weeks generating an ever-more efficient binary "Earth-like landform builder" --
obviously as with any EA the primary conceptual difficulty is some sort of effective fitness heuristic .. funnily enough, in a bizarre ontological twist, you may be best to match to the landforms in well-known computer games! - heh!! - now there's one for the books - but at any event in the ultimate stages you'd have to use a (perhaps online crowdsourced) human approach to whittle down the best ones.
of course..
alternately ..
Aeschylus could just ...
NOT JIGGLE THE VERTICES SO FAR. :--)
Your answer
Follow this Question
Related Questions
Check if a mesh has UV map at runtime 1 Answer
Conforming a mesh path to arbitrary surface - runtime 1 Answer
Runtime import of Collada files 3 Answers
Mesh creation during runtime 0 Answers
Procedural Mesh Generation - Split Arrays into sections 1 Answer