Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How to align the first 2/3 and last particles of a rope to do a realistic cable ?
#1
Hi,

I'm trying to do a RJ45 cable using Obi Rope. The thing is that I need to have a plug male on each side ( Start and End ) with their own scripts so I can't use the Start and End prefab feature of Obi Rope.

The first thing I did was to use Pin constraints which is working well in terms of logic. I can grab both start and end plugs and the rope. But in terms of realism, it's not good because pin constraint is on a particle so the cable is able to turn all around a plug.

So, I'm currently using the same logic that the moving ropes in the "RopeShowcase" sample scene by putting the rope as a child of a plug and using an Obi Handle and two fixed particles to force the cable to be aligned with the plug.

Here is what I have now.

[Image: 1522222496-what-i-want.png]

But I'm able to do it only on one side because, of course, the rope can't be a child of the start and end plug at the same time.

Also, if I grab the cable, the plug doesn't move according to it like when I'm using pin constraint. Which is logical because of the parenting and the Obi Handle.

I'm really out of ideas to manage how doing it by myself so if you can help me Sonrisa  

Thanks !
Killian
Reply
#2
(28-03-2018, 08:57 AM)Darkroll Wrote: The first thing I did was to use Pin constraints which is working well in terms of logic. I can grab both start and end plugs and the rope. But in terms of realism, it's not good because pin constraint is on a particle so the cable is able to turn all around a plug.

So, I'm currently using the same logic that the moving ropes in the "RopeShowcase" sample scene by putting the rope as a child of a plug and using an Obi Handle and two fixed particles to force the cable to be aligned with the plug.

I'm under the impression that you're trying to force a certain twist on the rope (to control its orientation along its length). This is not possible, ObiRope particles are just points in space, with no orientation.
Reply
#3
(28-03-2018, 12:26 PM)josemendez Wrote: I'm under the impression that you're trying to force a certain twist on the rope (to control its orientation along its length). This is not possible, ObiRope particles are just points in space, with no orientation.

Hi ! Thanks for your answer Guiño

But no, I'm not trying to control its orientation along its length. 

I mean, I just want to reproduce this, but on both sides. I already did it for one side (my first picture) but as I said, the rope needs to be child of the object which have the Obi Handle because the 2 first particles needs to be fixed to have this "curve" 

[Image: 1522237764-example.png]

and avoid the cable to fall down directly like this. To have a nice curve when I grab my RJ45 plug.

[Image: 1522238584-whatidontwant.png]

Thanks again Guiño
Reply
#4
Hi all,

I don't know if I should create a new thread or not, but I figured out how to do it and that could interest someone else.Guiño 

So, just to remind, I was trying to "force" the rope to have the firsts particles aligned when I grab one or both of the Start and EndPrefab. ( see my previous post )

Just an update, since last time I have added the possibility to grab the ObiRope following this thread and the VRTK_ObiRopeInteraction and VRTK_ObiRopeSolver scripts.

What I did is putting my RJ45 Prefab, which is grabbable, as a StartPrefab and EndPrefab of the ObiRope and modified the PlaceObjectAtCurveFrame's function in the ObiRope script. 

Actually, this function is replacing, every frame, the Start and End GameObject following the curve of the rope (position + rotation). So when I'm grabbing the rope, the prefabs are moving properly according to it. But the thing is I don't want that the rope "control" the GameObject's orientation while I grabbing it but conversely, I want to control the curve of the rope (not to twist it) while I grabbing a cable end. 

This is my code : 

Code:
private void PlaceObjectAtCurveFrame(CurveFrame frame, GameObject obj, Space space, bool reverseLookDirection)
       {
           // Check if the GameObject is grabbed or not
           if (obj.GetComponent<GrabbableBehaviour>().IsGrabbed == false && obj.GetComponent<PlugMaleBehaviour>().IsPlugged == false)
           {
               // If not, I'm using the default function
               if (space == Space.Self)
               {
                   Matrix4x4 l2w = transform.localToWorldMatrix;
                   obj.transform.position = l2w.MultiplyPoint3x4(frame.position);
                   if (frame.tangent != Vector3.zero)
                       obj.transform.rotation = Quaternion.LookRotation(l2w.MultiplyVector(reverseLookDirection ? frame.tangent : -frame.tangent),
                                                                         l2w.MultiplyVector(frame.normal));
               }
               else
               {
                   obj.transform.position = frame.position;
                   if (frame.tangent != Vector3.zero)
                       obj.transform.rotation = Quaternion.LookRotation(reverseLookDirection ? frame.tangent : -frame.tangent, frame.normal);
               }
               // Resetting of the mass of the two last or first particles
               if (reverseLookDirection)
               {
                   invMasses[invMasses.Length - 1] = 0.1f;
                   invMasses[invMasses.Length - 2] = 0.1f;
               }
               else
               {
                   invMasses[0] = 0.1f;
                   invMasses[1] = 0.1f;
               }
               PushDataToSolver(ParticleData.INV_MASSES);
           }
           else
           {
               // If it's grabbed then I fixed the particles by putting their masses to 0. Then I change their positions according to the position of the object using SetParticlePositions.
               if (reverseLookDirection)
               {
                   invMasses[invMasses.Length - 1] = 0;
                   invMasses[invMasses.Length - 2] = 0;
                   Oni.SetParticlePositions(Solver.OniSolver, new Vector4[] { obj.transform.position }, 1, particleIndices[particleIndices.Length - 1]);
                   Oni.SetParticlePositions(Solver.OniSolver, new Vector4[] { obj.transform.position + (obj.transform.forward * -0.02f) }, 1, particleIndices[particleIndices.Length - 2]);
               }
               else
               {
                   invMasses[0] = 0;
                   invMasses[1] = 0;
                   Oni.SetParticlePositions(Solver.OniSolver, new Vector4[] { obj.transform.position }, 1, particleIndices[0]);
                   Oni.SetParticlePositions(Solver.OniSolver, new Vector4[] { obj.transform.position + (obj.transform.forward * -0.02f) }, 1, particleIndices[1]);
               }

               PushDataToSolver(ParticleData.INV_MASSES);
           }
       }

I hope it's going to be helpful if someone wants to do the same Sonrisa . Please ask if you have any question about the code or how I did it.
Reply