(22-02-2023, 06:33 PM)Zombie1111 Wrote: I have two questions!
1: I tried disabling the obiPathSmoother component and it decreased the performance cost of each rope by around 50%. Is really 50% of the performance cost of a rope just rendering it?
Hi!
Yes, roughly. Rope rendering uses an inherently sequential algorithm, called "
parallel frame transport". Basically it involves choosing an initial orthonormal frame, and "transporting" it along a curve in a way that it minimizes the change in rotation along the curve. Then, you take these orthonormal frames and use them to build a mesh.
ObiPathSmoother is in charge of using parallel frame transport to generate a list of frames. It can also drop frames (decimation) and/or add extra frames (smoothing). Then, the ObiExtrudedRopeRenderer takes this list of frames and builds the actual mesh. Both generating the list of frames and building the mesh are fairly costly operations. The cost can be reduced considerably by using decimation (which results in less frames to process) and/or using a simpler rope section (less geometry to deal with).
(22-02-2023, 06:33 PM)Zombie1111 Wrote: 2: Is there anyway I could use obi rope to render a rope using joints? I have a array of positions I want the rope to go through. How does obi rope know where to render the rope?
An array of positions is not enough to render a rope, you also need
orientations. These can be either automatically calculated from positions trough parallel transport, or provided by the rigidbodies themselves. Either way, you can modify ObiPathSmoother to use your own positions as input instead of the particle's. The rest of the rendering pipeline would remain unchanged.
It's fairly simple to do. You only need to modify AllocateRawChunks() and PathFrameFromParticle() in ObiPathSmoother.cs.
- AllocateRawChunks() generates a list of initial empty frames, one per particle in the rope, taking into account discontinuities in the rope (cuts/torn parts). Modify it to generate one frame per entry in your positions array instead. In case you don't plan on having discontinuities, it's a trivial thing to do:
Code:
private void AllocateRawChunks(Vector3[] positions)
{
using (m_AllocateRawChunksPerfMarker.Auto())
{
rawChunks.Clear();
AllocateChunk(positions.Length);
}
}
- PathFrameFromParticle() sets the position/orientation of a frame to match a particle. Modify it to read the position from your array instead. Again if you have a continuous array of positions, it's an easy change:
Code:
private void PathFrameFromParticle(Vector3[] positions, ref ObiPathFrame frame, int arrayIndex, bool interpolateOrientation = true)
{
frame.position = positions[arrayIndex];
frame.thickness = 0.1f;
// optionally update frame thickness, color, etc.
// if you also have an array of quaternions/matrices that represent orientation, you can write frame.normal/tangent/bitangent too.
}
You'd also have to slightly modify GenerateSmoothChunks() which is the entry point of the entire rope rendering system, to pass an an array of positions instead of an ObiRopeBase instance.
kind regards,