Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Flipping cloth? ScaleX == -1?
#1
I want to flip the cloth, that is to set it's scale X to -1, and I have two problems:

1) Cloth turns black (as if in the shadows) after the flip, even if you turn off the shadows.
2) Cloth obviously is not solved properly. But this is not a problem, because I have already solved a similar case with FinalIK, what I need is to know precicely where the solving is taking place and to flip my mesh back again just before and just after the solving process.

I am using a double-sided shader based off of the Standard Shader.
Reply
#2
(13-08-2019, 05:29 PM)cubrman Wrote: I want to flip the cloth, that is to set it's scale X to -1, and I have two problems:

1) Cloth turns black (as if in the shadows) after the flip, even if you turn off the shadows.
2) Cloth obviously is not solved properly. But this is not a problem, because I have already solved a similar case with FinalIK, what I need is to know precicely where the solving is taking place and to flip my mesh back again just before and just after the solving process.

I am using a double-sided shader based off of the Standard Shader.

You cannot scale cloth itself, it does not make any sense mathematically speaking. You cannot describe the rotation/translation/size of a deformable object using a single affine transform. You can only scale the solver, as long as simulation is taking place in local scale. You can think of it as scaling the space around the cloth. See:
http://obi.virtualmethodstudio.com/tutor...space.html

Quote:Local space simulation allows to translate/rotate/scale the entire simulation result by scaling the solver transform.

Now, since mesh normals must be recalculated every frame for cloth simulation, flipping the mesh by scaling along one axis will also flip its normals (since triangle winding changes order: clockwise becomes counterclockwise and vice-versa). This cannot be avoided. Your best bet is to take this into account in the shader and un-flip the normals in the vertex shader if the scale is negative along one axis.

PD: wouldn't it be possible to just rotate the cloth 180 degrees on the Y axis? way simpler and cleaner than flipping using negative scale on one axis...
Reply
#3
(14-08-2019, 09:10 AM)josemendez Wrote: You cannot scale cloth itself, it does not make any sense mathematically speaking. You cannot describe the rotation/translation/size of a deformable object using a single affine transform. You can only scale the solver, as long as simulation is taking place in local scale. You can think of it as scaling the space around the cloth. See:
http://obi.virtualmethodstudio.com/tutor...space.html


Now, since mesh normals must be recalculated every frame for cloth simulation, flipping the mesh by scaling along one axis will also flip its normals (since triangle winding changes order: clockwise becomes counterclockwise and vice-versa). This cannot be avoided. Your best bet is to take this into account in the shader and un-flip the normals in the vertex shader if the scale is negative along one axis.

PD: wouldn't it be possible to just rotate the cloth 180 degrees on the Y axis? way simpler and cleaner than flipping using negative scale on one axis...

You are making things unnecessary confusing, it is clear from your answer that my suggested approach can fix absolutely everything: let me know where you compute stuff and I will make sure that my mesh is NOT flipped just before the calculation and flipped again (if necessary) just after the calculation. Then there would be no reason to do anything else, as normals won't be flipped (they aren't for all of my other meshes) and mesh simulation would be absolutely clean and clear. This approach works perfectly with Final IK - it will work with your plugin too.

Ofcourse I thought about rotating the character. But for now it would introduce quite a number of complications into the project and would require quiet a large body of work to be done to be worth it.
Reply
#4
(14-08-2019, 11:11 AM)cubrman Wrote: You are making things unnecessary confusing, it is clear from your answer that my suggested approach can fix absolutely everything: let me know where you compute stuff and I will make sure that my mesh is NOT flipped just before the calculation and flipped again (if necessary) just after the calculation. Then there would be no reason to do anything else, as normals won't be flipped (they aren't for all of my other meshes) and mesh simulation would be absolutely clean and clear. This approach works perfectly with Final IK - it will work with your plugin too.

Nope it won't fix anything, because of what I just explained. Final IK does not have to recalculate per-vertex mesh normals every frame (they can be directly transformed using the character bones). Obi however does, and does so using a cross product between face vertices, assuming clockwise vertex winding order (the standard approach to normal calculation, that is). As I explained in the previous answer, when you apply a negative scale to the mesh, clockwise orientation becomes counterclockwise thus reversing normals.

You cannot fix this by unflipping the mesh before the simulation and then flipping it again after. As I said the easiest fix is to negate the normals in your shader, when your object has negative scale.

Quote:(they aren't for all of my other meshes)

Of course, since all other meshes do not need to recalculate their normals from scratch every frame.

(14-08-2019, 11:11 AM)cubrman Wrote: Ofcourse I thought about rotating the character. But for now it would introduce quite a number of complications into the project and would require quiet a large body of work to be done to be worth it.

IMHO, dealing with negative scales is usually much more troublesome than dealing with rotations. Rotation is always representable in the real world, however negative scale isn't. Many lighting and physics operations just don't work with negative scale.
Reply
#5
(14-08-2019, 12:19 PM)josemendez Wrote: Nope it won't fix anything, because of what I just explained. Final IK does not have to recalculate per-vertex mesh normals every frame (they can be directly transformed using the character bones). Obi however does, and does so using a cross product between face vertices, assuming clockwise vertex winding order (the standard approach to normal calculation, that is). As I explained in the previous answer, when you apply a negative scale to the mesh, clockwise orientation becomes counterclockwise thus reversing normals.

You cannot fix this by unflipping the mesh before the simulation and then flipping it again after. As I said the easiest fix is to negate the normals in your shader, when your object has negative scale.


Of course, since all other meshes do not need to recalculate their normals from scratch every frame.


IMHO, dealing with negative scales is usually much more troublesome than dealing with rotations. Rotation is always representable in the real world, however negative scale isn't. Many lighting and physics operations just don't work with negative scale.

The only thing I am baffled about is this: why don't you just let me try and see for myself? Just tell me the best case scenario the best way to do what I want to do and let me fail on my own. Maybe then I will have other ideas. Flipping normals in the shader isn't hard for me - I am worried about cloth mesh jumping into colliders after flip though.
Reply
#6
(14-08-2019, 04:48 PM)cubrman Wrote: The only thing I am baffled about is this: why don't you just let me try and see for myself? Just tell me the best case scenario the best way to do what I want to do and let me fail on my own. Maybe then I will have other ideas. Flipping normals in the shader isn't hard for me - I am worried about cloth mesh jumping into colliders after flip though.

Huh I'm not holding you back in any way?. Simulation is done in FixedUpdate(), after WaitForFixedUpdate(), or in LateUpdate(), depending on your solver's update order. If you want to flip the mesh after simulation is done, then by all means go ahead. I'm just telling you it won't work in advance to save you headaches, explaining you why, and giving you a reasonable alternative.

The "clothMesh" property of ObiCloth contains the deformed mesh, just grab it and modify it in any way you want. Assuming your solver is updating the simulation in FixedUpdate, you can grab the results in Update, which is called by Unity always after FixedUpdate. Like:

Code:
void Update()
{
  Mesh mesh = cloth.clothMesh;
  // modify the mesh here
}

Quote:Flipping normals in the shader isn't hard for me - I am worried about cloth mesh jumping into colliders after flip though.
If you flip the normals in the shader, you cannot affect the simulation in any way if that's what you're worried about, only rendering. So the mesh won't jump into colliders or anything, if you only modify its shader.

Of course you could also flip the normals in Update as well (or scale the vertices of the mesh directly, one by one), but it would be staggeringly slow compared to using the vertex shader. (Note Obi performs mesh deformation in native code for performance reasons).
Reply
#7
Listen, I've just inserted the flipping code into ObiSolver.SimmulateStep(). It flips a GameObject into normal position just before the simulation and then flipps it back again at the end of the method. This did not help. And I am not talking about inverted normals - if they were the only issue, I would have flipped them in the shader by now - the problem is that the cloth kinda starts ignoring the colliders when flipped, even when I added the pre-flipping code. So I have a simple question: can I somehow ensure that the cloth can see the colliders (e.g. simmulate exactly like for the non-flipped cloth)? I have a very strong feeling that your suggestion to insert the flipping code into WaitForFixedUpdate() (meaning into the SimmulateStep()) was not the right one and you are omitting something. I have a strong suspission that I need to do something else to ensure that my GameObject is not flipped before the simulation, maybe change some variable? Btw, the Solver is sitting on a GameObject that itself gets flipped, maybe I should move it up the hierarchy so that it does not get flipped?
Reply
#8
(22-08-2019, 06:13 PM)cubrman Wrote: Listen, I've just inserted the flipping code into ObiSolver.SimmulateStep(). It flips a GameObject into normal position just before the simulation and then flipps it back again at the end of the method. This did not help. And I am not talking about inverted normals - if they were the only issue, I would have flipped them in the shader by now - the problem is that the cloth kinda starts ignoring the colliders when flipped, even when I added the pre-flipping code. So I have a simple question: can I somehow ensure that the cloth can see the colliders (e.g. simmulate exactly like for the non-flipped cloth)? I have a very strong feeling that your suggestion to insert the flipping code into WaitForFixedUpdate() (meaning into the SimmulateStep()) was not the right one and you are omitting something. I have a strong suspission that I need to do something else to ensure that my GameObject is not flipped before the simulation, maybe change some variable? Btw, the Solver is sitting on a GameObject that itself gets flipped, maybe I should move it up the hierarchy so that it does not get flipped?

Hi,

Well, if you perform flipping every frame in WaitForFixedUpdate(), your mesh is not flipped before the simulation. WaitForFixedUpdate happens right after all objects have had all FixedUpdate() calls executed, so by then simulation is done.

Keep in mind that most colliders do not support negative scaling. This is because there must be a consistent inside/outside for collisions to be efficient. So if you're flipping your character colliders you must do so together with the cloth mesh.
Reply
#9
(23-08-2019, 07:17 AM)josemendez Wrote: Hi,

Well, if you perform flipping every frame in WaitForFixedUpdate(), your mesh is not flipped before the simulation. WaitForFixedUpdate happens right after all objects have had all FixedUpdate() calls executed, so by then simulation is done.

Could you please just tell me where should I instert my flipping-back code so that I can make my test properly? Which method should I insert the code into, instead of SimmulateStep()? I am dead certain that if I actually execute my idea properly EVERYTHING will be fine, even the black normals would disappear.

Quote:Keep in mind that most colliders do not support negative scaling. This is because there must be a consistent inside/outside for collisions to be efficient. So if you're flipping your character colliders you must do so together with the cloth mesh.


This is exactly what I am doing. The cloth is going inside colliders even though everything is flipped: the cloth', the colliders', the solver's GameObjects. There is something wrong with your reasoning. My colliders are capsule colliders and sphere colliders - that is all, no mesh collider shenanigans.
Reply
#10
(23-08-2019, 10:03 AM)cubrman Wrote: Could you please just tell me where should I instert my flipping-back code so that I can make my test properly? Which method should I insert the code into, instead of SimmulateStep()?

As I already told you, set your solver update mode to FixedUpdate, then write your code after WaitForFixedUpdate:
https://docs.unity3d.com/ScriptReference...pdate.html

Your code should be executed after all physics steps in the frame, which is precisely what WaitForFixedUpdate accomplishes. See:
https://docs.unity3d.com/Manual/ExecutionOrder.html

You can also insert it in Update, or even LateUpdate.

(23-08-2019, 10:03 AM)cubrman Wrote: This is exactly what I am doing. The cloth is going inside colliders even though everything is flipped: the cloth', the colliders', the solver's GameObjects. There is something wrong with your reasoning. My colliders are capsule colliders and sphere colliders - that is all, no mesh collider shenanigans.

As I said, colliders (capsule, box and sphere colliders in particular) do not support negative scale. Are you 100% positive you're flipping them after the simulation?
Reply