Search Forums

(Advanced Search)

Latest Threads
(7.0.3) Updating skin con...
Forum: Obi Cloth
Last Post: CptnFabulous
Yesterday, 11:35 AM
» Replies: 2
» Views: 95
Extending rope by pulling...
Forum: Obi Rope
Last Post: trentthebaker
09-01-2026, 03:58 PM
» Replies: 0
» Views: 233
Managing dynamic constrai...
Forum: General
Last Post: josemendez
09-01-2026, 09:54 AM
» Replies: 1
» Views: 352
Emit rope like silly stri...
Forum: Obi Rope
Last Post: josemendez
09-01-2026, 09:17 AM
» Replies: 8
» Views: 904
Non-uniform particle dist...
Forum: Obi Rope
Last Post: chenji
09-01-2026, 02:56 AM
» Replies: 11
» Views: 4,111
Setting velocity to 0
Forum: Obi Cloth
Last Post: Qriva0
22-12-2025, 11:26 AM
» Replies: 7
» Views: 1,190
Cloth backside collision ...
Forum: Obi Cloth
Last Post: Qriva0
19-12-2025, 10:07 AM
» Replies: 7
» Views: 1,475
Following Seas - Made wit...
Forum: Made with Obi
Last Post: josemendez
19-12-2025, 09:56 AM
» Replies: 1
» Views: 400
Obi 8: what's coming up
Forum: Announcements
Last Post: josemendez
12-12-2025, 08:41 AM
» Replies: 8
» Views: 2,063
Correct way to update mes...
Forum: Obi Fluid
Last Post: Voxelboy
10-12-2025, 12:48 AM
» Replies: 2
» Views: 668

 
  How to let Rod not streching part of the mesh
Posted by: chenji - 30-11-2025, 01:07 AM - Forum: Obi Rope - Replies (3)

Hi,

I have a Obi rod with uses Obi rod mesh renderer. The rod contains two parts: handle and body. There are lots of type of this rod and the only difference is the length of the rod body, the handle mesh are same in these different types. As Obi rod mesh renderer only takes one mesh and will streching all the mesh for the specified rod length, now I have to make lots of meshes to get what I need. Is there any trick to only use one mesh (or two split mesh for handle and body), let Obi rod strech only the body part of the rod mesh, and let the whole rod's physics behavior controlled by Obi rod?

Print this item

  Particle Attachment does not work
Posted by: Tomski - 27-11-2025, 06:04 AM - Forum: Obi Rope - Replies (5)

Hi 
I am working on a project using obi rope, I am trying to setup 2 start/end close to each other points to attach rope with an angle to a pin, I use tangled rope example and documentation as reference. 
I am observing very random behaviour of the Attachment functionality. i.e. For basic rope with 2 start and 2 end points all works fine, but SOMETIMES randomly adding new middle point(s) breaks the setup, one or both of the attachment points stops working completely, and I am having hard time fixing it. I tried everything I can thing of: 
- reassign particle group 
- rename and reassign particle group 
- reposition start/end points slighlty 
- change resolution in blueprint 

When testing even with simple 1 end point, the particle attachment will not work (attach).

What can cause such behaviour ? I spend a lot of time trying to figure this one out :/ 


Also side note: 
In unity 2022.3.55 after a while of editing ropes usually 5 -10 mins, my inspector gets stuck and I am unable to select anything anymore in the scene, and only way to fix it is editor restart. I am quite sure this is causes byt Obi as have two other projects on same unity and never observed this. 

Also I am having errors when editing rope, or entering play mode while edit mode is active. 

Lastly there seems to be an issue with cursor/rope reel example in tangled rope example scene, if these two components are enabled the rope will jitter permanently quite a lot. Very noticeable in editor and even more so on mobile. What is causing this? are there any other examples to reel the rope that work ?

Any ideas how to solve this issues? 

Is there any preffered unity version to use ? I am starting new project so it's viable to update.

Thank you in advance

Print this item

  Obi 8: what's coming up
Posted by: josemendez - 21-11-2025, 09:52 AM - Forum: Announcements - Replies (8)

Hi all!

I've been working on Obi 8 for a few weeks now, and wanted to talk about what we're doing with it and get some feedback if possible.

The main driving force behind Obi 8 is making it more flexible. Currently, the only way to customize particle behavior is to add external forces and/or modify their positions outside the main solver loop. This is fine in many cases, but will fail miserably in others, specially when tight coupling with existing constraints is required and doing stuff every substep/iteration is a necessity. In these cases you'd be forced to crack open the engine and mess with internals, which isn't an appealing prospect.

So the idea is to rewrite a large part of the engine and expose an API that allows you to write entirely custom constraints. These get solved along with all built-in constraints, in fact, we're rewriting all built-in constraints using this new API. This is how it looks:

Constraints are split into 3 classes: a data container, a burst implementation (optional) and a compute implementation (optional). For instance, bend constraints would consist of:

  • ObiBendConstraintData (derived from ObiConstraintData)
  • ObiBurstBendConstraints (derived from ObiBurstConstraints)
  • ObiComputeBendConstraints (derived from ObiComputeConstraints)

To register a new constraint type in a solver, there's a generic RegisterConstraintType method that takes the name used to display constraint parameters in the solver and the parameters that should be shown in the ObiSolver inspector:

Code:
solver.RegisterConstrainType<T>(string name, ConstraintParameters params) where T : ObiConstraintData

The ability to pass custom constraint parameters allows your constraints to have their own mini-inspector in the ObiSolver component, to have all related parameters neatly presented along built-in ones. This has allowed us to move what were solver-global parameters (like ambient wind direction which is used by aerodynamic constraints, or collision margin which is used by collisions) to the constraints that actually depend on them, which is less confusing:

[Image: oY3y1Ee.png]

for example, bend constraints register themselves like so:

Code:
solver.RegisterConstrainType<ObiBendConstraintData>("Bend", new BendConstraintParameters());

Once you've registered a new type of constraints, you can add implementations for the Burst and Compute backends. These are optional, eg. if you don't provide a Compute implementation then these constraints won't do anything when using the Compute backend. I don't recommend not adding any implementation though! Guiño

Code:
solver.RegisterBurstConstraintsImplementation<T, U>() where T : ObiConstraintData where U : ObiBurstConstraints;
solver.RegisterComputeConstraintsImplementation<T, U>() where T : ObiConstraintData where U : ObiComputeConstraints

The constraint data class is very simple: you just declare data buffers (ObiNativeLists) to hold data for each constraint, and provide implementations to add constraints, resize the buffers, clear and dispose them. For instance bend constraint data looks like this:

Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

namespace Obi
{
    [Serializable]
    public class ObiBendConstraintData : ObiConstraintData
    {
        /// <summary>
        /// one float per constraint: the rest bend distance.
        /// </summary>
        [HideInInspector] public ObiNativeFloatList restBends = new ObiNativeFloatList();               

        /// <summary>
        /// two floats per constraint: max bending and compliance.
        /// </summary>
        [HideInInspector] public ObiNativeVector2List bendingStiffnesses = new ObiNativeVector2List();

        /// <summary>
        /// two floats per constraint: plastic yield and creep.
        /// </summary>
        [HideInInspector] public ObiNativeVector2List plasticity = new ObiNativeVector2List();

        public override int priority => 100;
        public override int workItemSize => 4;

        public int AddConstraint(int batchIndex, Vector3Int indices, float restBend)
        {
            int constraintIndex = RegisterConstraint(batchIndex, indices.x, indices.y, indices.z);

            restBends[constraintIndex] = restBend;
            bendingStiffnesses[constraintIndex] = Vector2.zero;
            plasticity[constraintIndex] = Vector2.zero;

            return constraintIndex;
        }

        protected override void ResizeDataBuffers(int constraintCount)
        {
            restBends.ResizeUninitialized(constraintCount);
            bendingStiffnesses.ResizeUninitialized(constraintCount);
            plasticity.ResizeUninitialized(constraintCount);
        }

        protected override void CopyConstraintData(ObiActor actor, ObiConstraints source, int srcIndex, int dstIndex, int count)
        {
            var batch = source as ObiBendConstraintData;
            var user = actor as IBendConstraintsUser;

            if (batch != null && user != null)
            {
                restBends.CopyFrom(batch.restBends, srcIndex, dstIndex, count);
                bendingStiffnesses.CopyReplicate(new Vector2(user.maxBending, user.bendCompliance), dstIndex, count);
                plasticity.CopyReplicate(new Vector2(user.plasticYield, user.plasticCreep), dstIndex, count);
            }
        }

        public override bool EnabledForActor(ObiActor actor)
        {
            var user = actor as IBendConstraintsUser;
            return user != null && user.bendConstraintsEnabled;
        }
        protected override void OnClear()
        {
            restBends.Clear();
            bendingStiffnesses.Clear();
            plasticity.Clear();
        }

        protected override void OnDispose()
        {
            restBends.Dispose();
            bendingStiffnesses.Dispose();
            plasticity.Dispose();
        }
    }
}

Concrete implementations for the burst/compute backends need to implement a method to retrieve constraint data, and a method to actually enforce the constraints (that gets called once per solver iteration of that constraint type). Burst bend constraints look like this:

Code:
using UnityEngine;
using Unity.Jobs;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
using Unity.Burst;
using System.Collections;

namespace Obi
{
    public class ObiBurstBendConstraints: ObiBurstConstraints
    {
        BendConstraintsBatchJob projectConstraints;

        public override void SetConstraintData()
        {
            ObiBendConstraintsData b = abstraction as ObiBendConstraintsData;

            this.lambdas = b.lambdas.AsNativeArray<float>();
            this.batches = b.batches.AsNativeArray<int4>();

            projectConstraints.workItems = b.workItems.AsNativeArray<int2>();
            projectConstraints.particleIndices = b.particleIndices.AsNativeArray<int>();
            projectConstraints.restBends = b.restBends.AsNativeArray<float>();
            projectConstraints.stiffnesses = b.bendingStiffnesses.AsNativeArray<float2>();
            projectConstraints.plasticity = b.plasticity.AsNativeArray<float2>();
            projectConstraints.lambdas = this.lambdas;
        }

        public override JobHandle SolvePositions(JobHandle inputDeps, float stepTime, float substepTime, int steps, float timeLeft)
        {
            projectConstraints.positions = solverImplementation.positions;
            projectConstraints.invMasses = solverImplementation.invMasses;
            projectConstraints.deltas = smooth ? solverImplementation.positionDeltas : solverImplementation.positions;
            projectConstraints.deltaTime = substepTime;
            projectConstraints.countConstraints = smooth ? 1 : 0;
            projectConstraints.workItemSize = workItemSize;

            for (int i = 0; i < batches.Length; ++i)
            {
                projectConstraints.offset = batches[i].x;
                inputDeps = projectConstraints.Schedule(batches[i].y, 8, inputDeps);
            }

            if (smooth)
                inputDeps = ApplyDeltas(inputDeps);

            return inputDeps;
        }

        [BurstCompile]
        public struct BendConstraintsBatchJob : IJobParallelFor
        {
            [ReadOnly] public NativeArray<int2> workItems;
            [ReadOnly] public NativeArray<int> particleIndices;

            [ReadOnly] public NativeArray<float4> positions;
            [ReadOnly] public NativeArray<float2> stiffnesses;
            [ReadOnly] public NativeArray<float2> plasticity; //plastic yield, creep
            [ReadOnly] public NativeArray<float> invMasses;

            [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] public NativeArray<float> restBends;
            [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] public NativeArray<float> lambdas;
            [NativeDisableContainerSafetyRestriction] [NativeDisableParallelForRestriction] public NativeArray<float4> deltas;

            [ReadOnly] public float deltaTime;
            [ReadOnly] public float sor;
            [ReadOnly] public int countConstraints;
            [ReadOnly] public uint workItemSize;
            [ReadOnly] public int offset;

            public void Execute(int w)
            {
                var wi = workItems[offset + w];

                for (int i = wi.x, j = 0; j < workItemSize; ++i, ++j)
                {
                    if ((wi.y & (1 << j)) == 0) continue;

                    int p1 = particleIndices[i * 3];
                    int p2 = particleIndices[i * 3 + 1];
                    int p3 = particleIndices[i * 3 + 2];

                    float w1 = invMasses[p1];
                    float w2 = invMasses[p2];
                    float w3 = invMasses[p3];

                    float wsum = w1 + w2 + 2 * w3;

                    float4 bendVector = positions[p3] - (positions[p1] + positions[p2] + positions[p3]) / 3.0f;
                    float bend = math.length(bendVector);

                    float constraint = bend - restBends[i];

                    constraint = math.max(0, constraint - stiffnesses[i].x) +
                                 math.min(0, constraint + stiffnesses[i].x);

                    // plasticity:
                    if (math.abs(constraint) > plasticity[i].x)
                        restBends[i] += constraint * plasticity[i].y * deltaTime;

                    // calculate time adjusted compliance
                    float compliance = stiffnesses[i].y / (deltaTime * deltaTime);

                    // since the third particle moves twice the amount of the other 2, the modulus of its gradient is 2:
                    float dlambda = (-constraint - compliance * lambdas[i]) / (wsum + compliance + BurstMath.epsilon);
                    float3 correction = 2 * dlambda * bendVector.xyz / (bend + BurstMath.epsilon);

                    lambdas[i] += dlambda;

                    deltas[p1] += new float4(-correction * w1, countConstraints);
                    deltas[p2] += new float4(-correction * w2, countConstraints);
                    deltas[p3] += new float4(correction * 2 * w3, countConstraints);
                }
            }
        }
    }
}

The Compute equivalent is very similar, but instead of a Job it uses a compute shader to so the same work.

Some constraints are not just static relationships between particles, but require colliders or particle neighbor information that changes over time. We're making sure to expose collider and particle neighbor data (gathered during collision detection) as well so that it can be used in custom constraints. You'll be able to, for example, dynamically create constraints between particles that come in the vicinity of each other, and destroy the constraints once they're under too much stress.

Along with this, we're rewritting constraint coloring/batching. Instead of batching individual constraints, we group them into tiny chunks of 2-8 constraints called work items, and batch the work items instead. The coloring algorithm used in blueprint generation has been also upgraded from greedy coloring to recursive largest-first. Both changes result in considerably less batches, and a speedup of around 10-30% depending on the scene.

So my hope is for Obi 8 to be simpler, faster and a lot more flexible all at once.

I'm also tinkering with the idea of allowing custom particle attributes (so that your particles can have position, mass, political affiliation and social security number if you so choose) and custom colliders. This is in very early stages so the API hasn't come together yet.

Let me know what you think, what you'd like to see in the future or ask me if a specific use case will be possible. This way the thing that ends up being shipped will meet your needs better! Any feedback is welcome.

kind regards

Print this item

  Console spam on ComputeCollisionWorld
Posted by: Koolio - 17-11-2025, 05:37 PM - Forum: Obi Rope - Replies (2)

Whenever I click on the ComputeCollisionWorld  I get this spam.. only after deleting this gameobject and then,
   

Code:
ArgumentNullException: Value cannot be null.
Parameter name: buffer
UnityEngine.Bindings.ThrowHelper.ThrowArgumentNullException (System.Object obj, System.String parameterName) (at <a79a791492ad46a4a58f705c3ae06f55>:0)
UnityEngine.ComputeShader.Internal_SetGraphicsBuffer (System.Int32 kernelIndex, System.Int32 nameID, UnityEngine.GraphicsBuffer buffer) (at <a79a791492ad46a4a58f705c3ae06f55>:0)
UnityEngine.ComputeShader.SetBuffer (System.Int32 kernelIndex, System.Int32 nameID, UnityEngine.GraphicsBuffer buffer) (at <a79a791492ad46a4a58f705c3ae06f55>:0)
UnityEngine.ComputeShader.SetBuffer (System.Int32 kernelIndex, System.String name, UnityEngine.GraphicsBuffer buffer) (at <a79a791492ad46a4a58f705c3ae06f55>:0)
Obi.ComputeSolverImpl.UpdateBounds (Obi.IObiJobHandle inputDeps, System.Single stepTime) (at Assets/Obi/Scripts/Common/Backends/Compute/Solver/ComputeSolverImpl.cs:601)
Obi.ObiSolver.UpdateBounds () (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:1920)
Obi.ObiSolver.LateUpdate () (at Assets/Obi/Scripts/Common/Solver/ObiSolver.cs:1217)


 going to Obi Solver and selecting Backend Burst(CPU) and then changing it back to (GPU) will it fix it, unless I click on it again then same issue.
   

6.2/6.3 latest versions, this issue happens from what I've seen.

Print this item

  Animal Style - Fluid Cooking Game - Demo Available
Posted by: scoull - 13-11-2025, 07:13 PM - Forum: Made with Obi - Replies (1)

I am excited to announce Animal Style, and the Demo is available now!

https://store.steampowered.com/app/37972...mal_Style/

This games uses Obi Fluid for the main puzzle mechanics. In addition to saucing foods, you can cover the customers, walls, and kill zombies with Obi Fluid sauces!

Print this item

  Distance field default offset
Posted by: Qriva0 - 13-11-2025, 03:59 PM - Forum: General - Replies (1)

Piece of small feedback - obi SDF adds padding equal to 0.2f during generation, I think it might be wise to make into some parameter or global setting, because for meshes with small scale 0.2 is huge, while for big mesh it's very small constant and it affects result when mesh is open, on edge etc.

Print this item

  Graphical twist on rope
Posted by: goosejordan - 10-11-2025, 11:21 PM - Forum: Obi Rope - Replies (2)

Hi,

is it possible to remove the twist on the rope that is caused by movement upstream? I understand that the rope component doesn't store and calculate twist like rods do. So twist is naturally following the consecutive angles of the particles.

It should be possible in each particle iteration seek to blend the twist toward an upward direction, right? Any advice on where to look?

Here's a gif of the effect. Now when I tried to record it it only did so weakly, but it can look very jittery if the rope jitters a lot upstream.
https://drive.google.com/file/d/1BUROTTK...drive_link

Thanks in advance!

Print this item

  Helper functions/commands
Posted by: kurm1s0 - 10-11-2025, 06:03 PM - Forum: Obi Rope - Replies (3)

Hello! Very nice plugin, results look way better than anything I have seen in games!

I have a question about making working with the plugin easier.

Are there any kind of helper scripts/commands that let you easily connect two objects with a rope in the editor or ar runtime? 

I am not really a programmer so it's not that easy for me to create such things. 

I am just wondering maybe people have made such things in the past. 

Thanks, really enjoying playing around with this plugin!

Print this item

  Dynamic particle attachment question
Posted by: MEPETAMINALS - 08-11-2025, 07:25 PM - Forum: Obi Cloth - Replies (3)

Hi -- I've read through the manual and tried a number of things, but I'm encountering an issue with particle attachments that I'm hoping to get some insight on.

You can see in the video that the corner of the sail (this is a dynamic particle attachment to a rigidbody at the end of the rope) tends to jitter considerably.

I'd thought that this was a matter of solver settings, but have been unable to make any meaningful improvements -- even cranking iterations up to goofy amounts (20+).

Regarding settings, collision is off, both on a cloth blueprint/particle level, and for the obi rigidbodies involved. The mass of the attached rigidbody and the attaching particles are close (I've tried varying these as well. The only change is that if I increase the mass of the particles to be considerably higher than the attached rb, the issue reverses and the rigidbody starts flickering.)

Worth noting that the issue remains even if the attachment is set to static, and the attached rb is kinematic.

This issue is unchanged on CPU/GPU solving.
This issue is unchanged on RB Interpolation ON/OFF (For both the solver and hierarchy of rigidbodies).

I'm inclined to think that it's due to being a child of a rigidbody, but from my understanding that should be permissable. (Essentially the ship is a rigidbody, which is a parent to all other dynamic elements.)

Suggestions appreciated.

https://www.youtube.com/watch?v=ya3jV_JDYSU

Print this item

  Endoscope rod help
Posted by: Raidan - 08-11-2025, 05:21 PM - Forum: Obi Rope - Replies (2)

Simulating Endoscope Tip Articulation with Obi Rod - Seeking Implementation Advice  

I'm developing an endoscopy training simulator and need to simulate a flexible endoscope using Obi Rod (due to the torsion support) that interacts with an organ Obi Softbody. I'm looking for guidance on the best approach to implement the endoscope.

Real endoscope Behavior

An endoscope consists of:
Flexible insertion tube (~160-180cm): Can be pushed, pulled, and rotated along its axis
Articulated tip section (~10-15cm): The distal end that can bend up to 180° in four directions (up/down/left/right) using control knobs at the handle
Key characteristic: The tip bending is mechanically isolated from the main shaft via internal pull-wires. When you deflect the tip, it doesn't create relevant opposing forces in the insertion tube body.

What I Need to Achieve



1. Independent Tip Deflection
- The tip section (last 10-15cm) needs to bend smoothly and progressively in response to user input, creating a U shape where the tip points back towards the endoscope shaft
This bending should NOT propagate forces backward into the main insertion tube. I've done some tests changing particle velocities to shape the tip, and due to the constraints, the rest of the shaft ends up moving while bending its tip.
The tip can be undergoing a tip deflection while the entire scope is simultaneously being pushed/pulled/rotated, as the endoscope may be moving while the tip is being deflected or held while keeping a specific deflection value. Due to this, freezing the particles to avoid force propagation is not an option, as the endoscope still needs to moove freely.

2. Physical Connection
- Despite the mechanical isolation of the articulation mechanism, the tip is physically part of the same tube
- The tip must follow when the body is moved (pushed, pulled, or navigating through the organ)
- Both sections should interact with the environment (organ walls) naturally, which is a Obi Softbody with surface collisions

3. Roll/Twist Propagation
- When the insertion tube is rotated/twisted at the handle, this rotation should propagate all the way through to the tip, which already happens thanks to rod behaviour.
- This is separate from the tip deflection - the tip can be both deflected AND rotated

Questions for the Community

Main Question
What's the best approach in Obi to implement this articulated structure where the tip can deflect independently without forces propagating to the body? I've done several test and thought of several implementations

**Option A**: Single Obi Rod
- Modify particle velocities/positions for just the tip section
- Somehow prevent forces from propagating to the rest of the rod
- How would I achieve force isolation in this case?

**Option B**: Two Separate Obi Rods
- Body rod + Tip rod connected via ObiStitcher (or other method). Attachments seem too rigid for my needs.
- Apply deflection forces only to the tip rod, and propagate roll from body to tip rod manually?
- Does stitching provide any means for force isolation, or do forces still propagate?

**Option C**: Different approach entirely?
- Is there a better way to handle this in Obi that I'm not considering?
- Custom constraints? Different actor types?

Any advice on architecture, implementation approaches, or Obi best practices for this type of articulated simulation would be greatly appreciated!  Gran sonrisa Gran sonrisa

Thanks!

Print this item