Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    SplineIK Rotation jitter problem

    General Talk
    2
    7
    1.5k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • chuanzhenC
      chuanzhen
      last edited by chuanzhen

      Hi,
      I found that IK_spline tag will cause joint rotation jitter when moving the controller under certain circumstances.
      The picture(pic1) below shows this situation, showing the axes of the joint to make it easier to see.
      splineIK问题.gif
      pic1

      Is this a bug or a wrong way of using it?

      I use the parallel transport method to expand to get a more stable rotational mixing. The picture(pic2) below is a comparison. The thicker coordinate axis shows the result of using parallel transfer mixing, which is more stable.
      splineIK问题解决.gif
      pic2

      Although the rotational jitter problem has been solved, I would like to understand the cause of the rotational jitter. The following is the c4d file where this problem occurs.

      splineIK_rotation_problem.c4d

      Thanks for any help!

      相信我,可以的!

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @chuanzhen
        last edited by ferdinand

        Hello @chuanzhen,

        Thank you for reaching out to us. When you say you are using Parallel Transport, which is just a subject of math, I assume you mean "the" parallel transport frame(s) algorithm we talked about for example here and not something more fancy like rotation minimizing frames (which also realizes parallel transport).

        I would say you simply have a bug in your algorithm, because naive parallel transport is stable and its shortcoming is that it does not react to sudden changes in curvature very responsively (as you always drag the sum of the past banking values with you by carrying over the normals). I.e., its weakness is the exact opposite of what you show us. As declared in our forum guidelines, I cannot help you too much with debugging and general math subjects (I also do not see any code in your file or on the forum).

        While it can be necessary in some cases to write your own parallel transport, specifically when you need more control over how changes in curvature translate into the banking of the frames, you can also just use c4d.utils.SplineHelp. It can construct frames on the vertices of a spline for you. We talked not too long ago about the subject in this thread, I also gave an explanation and a code example there. The problem was very similar to yours, aligning cones with a spline.

        In this case you simply construct a linear spline on your bones, and then use c4d.utils.SplineHelp to construct the frames. Afterwards you could swizzle the frames or do other post-processing if you do not like other aspects of the output.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        chuanzhenC 1 Reply Last reply Reply Quote 0
        • chuanzhenC
          chuanzhen @ferdinand
          last edited by

          Hi @ferdinand
          Thank you for your detailed reply. As you said 'bug', just direct parallel transport cannot directly obtain as stability control as in the picture. The working method I use is to perform parallel transport in segments(2 control is a segment), in both forward and reverse directions. After two time parallel transport, then mix the rotation.This can achieve flexible control by the controller. The bones also ensure his stability.

          I would like to know more about why the built-in IK_Spline Tag causes such jitter in c4d files and pic. Is the IK_Spline Tag not working stably enough, or is there another problem?

          相信我,可以的!

          ferdinandF 1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand @chuanzhen
            last edited by ferdinand

            Hey @chuanzhen,

            just direct parallel transport cannot directly obtain as stability control as in the picture

            I strongly doubt that, the run of the mill parallel transport algorithm, aka PFT, has many flaws but it will pretty much smooth out everything out under the sun (which is also one of its flaws). Jitter is the last thing I would expect from PFT. I might be overlooking here an important detail in your setup, but this seems very unlikely to me, especially because my setup below works fine.

            I do not see jitter in the file you have provided, can you be more specific?

            Below I have provided a very quick and dirty setup for constructing the frames on a spline. It is unclear to me if you want to construct the frames of the spline input of a Spline-IK, or if you want to construct the frames on the bones. A chose the slightly more complicated case of first constructing spline for the bone chain.

            I kept the example very loose, which is why the nulls are slightly offset, as I assume all bones always to have the same length, instead of doing the busy working of figuring out where the offsets for the bones must lie on the spline.

            Cheers,
            Ferdinand

            File:
            splineik_rotation_problem.c4d
            Result:

            Code:

            """Constructs frames for a list of input objects interpreted as a spline.
            """
            
            from typing import Optional
            import c4d
            
            doc: c4d.documents.BaseDocument # The document evaluating this tag
            op: c4d.BaseTag # The Python scripting tag
            
            def iter(node: c4d.GeListNode | None) -> c4d.GeListNode:
                """Yields all descendants of #node and #node itself.
                """
                if not isinstance(node, c4d.GeListNode):
                    return
            
                yield node
                for child in node.GetChildren():
                    for descendant in iter(child):
                        yield descendant
            
            def ConstructSpline(offsets: list[c4d.Vector]) -> c4d.SplineObject:
                """Constructs a linear spline from the given offsets and builds its cache.
                """
                spline: c4d.SplineObject = c4d.SplineObject(len(offsets), c4d.SPLINEOBJECT_TYPE_LINEAR)
                if not spline:
                    raise MemoryError()
            
                spline.SetAllPoints(offsets)
                spline.Message(c4d.MSG_UPDATE)
            
                temp: c4d.documents.BaseDocument = c4d.documents.BaseDocument()
                if not temp:
                    raise MemoryError()
            
                temp.InsertObject(spline)
                if not temp.ExecutePasses(c4d.threading.GeGetCurrentThread(), False, True, True, c4d.BUILDFLAGS_NONE):
                    raise RuntimeError()
            
                spline.Remove()
                temp.Flush()
            
                return spline
            
            
            def main() -> None:
                """
                """
                # Get the user data inputs.
                boneRoot: c4d.BaseObject | None = op[c4d.ID_USERDATA, 2]
                frameRoot: c4d.BaseObject | None = op[c4d.ID_USERDATA, 3]
            
                # Get the list of global offsets from the bones and the list of null objects to set.
                offsets: list[c4d.Vector] = [n.GetMg().off for n in iter(boneRoot)]
                nulls: list[c4d.BaseObject] = [n for n in iter(frameRoot)]
                if len(offsets) != len(nulls):
                    raise RuntimeError()
            
                # Construct the spline object and init the helper.
                spline: c4d.SplineObject = ConstructSpline(offsets)
                helper: c4d.utils.SplineHelp = c4d.utils.SplineHelp()
                helper.InitSplineWithUpVector(spline, upvector=c4d.Vector(0, 1, 0)                                    )
                count: int = spline.GetPointCount()
            
                # Iterate over all points and compute a transported frame for each of them. I am just blindly
                # assuming here that each bone will have the same length, which of course does not hold true.
                # I was too lazy to do all the busy work, but what you would have to do is compute/get the length
                # of all bones, then compute the sum of them, get the length of the spline, and with that 
                # information compute the offsets #t.
                for i in range(spline.GetPointCount()):
                    t: float = (i + 1.) / count
                    mg: c4d.Matrix = helper.GetMatrix(t, realoffset=True)
                    nulls[i].SetMg(mg)
            

            MAXON SDK Specialist
            developers.maxon.net

            chuanzhenC 1 Reply Last reply Reply Quote 0
            • chuanzhenC
              chuanzhen @ferdinand
              last edited by

              Hey @ferdinand
              Thanks for your reply!
              The video shows that the new file(splineIK_rotation_problem.c4d ) has rotational jitter at frames 6-7 and 49-50.

              The python tag of the new file contains the solution code, you can see it in the file.

              相信我,可以的!

              ferdinandF 1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand @chuanzhen
                last edited by ferdinand

                Hey @chuanzhen,

                you mean the twisting motion of the bones aligned to the spline? That comes from the Twist of the IK-Spline being set to World. But with such questions you must go to our support center. We cannot provide support on end-user questions here; the problem/twisting happens with no code present in the scene.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

                chuanzhenC 1 Reply Last reply Reply Quote 0
                • chuanzhenC
                  chuanzhen @ferdinand
                  last edited by

                  @ferdinand Thanks

                  相信我,可以的!

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post