Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Trying to add DistanceConstraint for my TearableCloth but getting IndexOutOfRange
#11
(04-08-2022, 08:21 PM)snowtv Wrote: Hello, I sent an email with the sample project yesterday, did you receive it?

Hi,

Yes I did receive it, but haven’t had time to look into it today. Will get back to you tomorrow morning.

Kind regards,
Reply
#12
Hi!

Took a look at your project, there's a couple things that keep it from working:

1) You're not actually adding the batch to the solver. You need to call batch.AddToSolver(obiSolver); at the end of AttachParticlePairInColon().

2) You're adding the constraints in your script's Start(). When actors get added to the solver, and the constraint batches marked dirty to be rebuilt at the beginning of the next frame. So there's a pretty good chance you're adding the constraints before the batches even exist in the solver. As a result, you're adding new batches only for them to be wiped clean once the actors get added to the solver.

Either wait for one frame to add the constraints, or add them at some other point after the actors have been instantiated.

kind regards,
Reply
#13
(05-08-2022, 07:39 AM)josemendez Wrote: Hi!

Took a look at your project, there's a couple things that keep it from working:

1) You're not actually adding the batch to the solver. You need to call batch.AddToSolver(obiSolver); at the end of AttachParticlePairInColon().

2) You're adding the constraints in your script's Start(). When actors get added to the solver, and the constraint batches marked dirty to be rebuilt at the beginning of the next frame. So there's a pretty good chance you're adding the constraints before the batches even exist in the solver. As a result, you're adding new batches only for them to be wiped clean once the actors get added to the solver.

Either wait for one frame to add the constraints, or add them at some other point after the actors have been instantiated.

kind regards,

Hi, I applied the changes. And I'm having the following error:

Code:
System.IndexOutOfRangeException: Index {0} is out of range of '{1}' Length.
Thrown from job: Obi.BurstDistanceConstraintsBatch.DistanceConstraintsBatchJob
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Burst -> Enable Compilation) to inspect full exceptions & stacktraces.
Reply
#14
(05-08-2022, 08:48 PM)snowtv Wrote: Hi, I applied the changes. And I'm having the following error:

Code:
System.IndexOutOfRangeException: Index {0} is out of range of '{1}' Length.
Thrown from job: Obi.BurstDistanceConstraintsBatch.DistanceConstraintsBatchJob
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Burst -> Enable Compilation) to inspect full exceptions & stacktraces.

I applied the same changes I outlined above, but I get no exceptions and the end of the colon mesh is correctly sewn shut. Could you disable Burst (as the error suggests) to see the full stack trace, so that we can see where the error is originating?
Reply
#15
(08-08-2022, 07:13 AM)josemendez Wrote: I applied the same changes I outlined above, but I get no exceptions and the end of the colon mesh is correctly sewn shut. Could you disable Burst (as the error suggests) to see the full stack trace, so that we can see where the error is originating?

Hi, I switched the backend from Burst to Oni, and I'm not getting errors anymore, and I can also see the colon sewn shut.

Is there a way to debug while enabling Burst?

Thank you very much!
Reply
#16
(08-08-2022, 09:31 PM)snowtv Wrote: Hi, I switched the backend from Burst to Oni, and I'm not getting errors anymore, and I can also see the colon sewn shut.



Thank you very much!

Hi,

By "disabling Burst" I meant disabling the Burst compiler, not switching to another backend.

(08-08-2022, 09:31 PM)snowtv Wrote: Is there a way to debug while enabling Burst?

This is exactly what disabling Burst accomplishes. The Burst backend and the Burst compiler are two different things. The "Burst" backend is named that way because it makes use of Unity's Burst compiler to compile its code. Disabling the Burst compiler will allow Unity to provide full stack traces for the error, which will make debugging much easier - as the error message itself suggests to do.

To disable Burst, go to Jobs->Burst->Enable compilation and untick "Enable compilation".
See: https://docs.unity3d.com/Packages/com.un...index.html

kind regards,
Reply
#17
(09-08-2022, 07:23 AM)josemendez Wrote: Hi,

By "disabling Burst" I meant disabling the Burst compiler, not switching to another backend.


This is exactly what disabling Burst accomplishes. The Burst backend and the Burst compiler are two different things. The "Burst" backend is named that way because it makes use of Unity's Burst compiler to compile its code. Disabling the Burst compiler will allow Unity to provide full stack traces for the error, which will make debugging much easier - as the error message itself suggests to do.

To disable Burst, go to Jobs->Burst->Enable compilation and untick "Enable compilation".
See: https://docs.unity3d.com/Packages/com.un...index.html

kind regards,

Thanks for the instructions!

I disabled the compilation and here is the error message:


Code:
IndexOutOfRangeException: Index 0 is out of range of '0' Length.
Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Collections.NativeArray`1[T].CheckElementReadAccess (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Collections.NativeArray`1[T].get_Item (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Obi.BurstDistanceConstraintsBatch+DistanceConstraintsBatchJob.Execute (System.Int32 i) (at Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraintsBatch.cs:101)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct`1[T].Execute (T& jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete(JobHandle&)
Unity.Jobs.JobHandle:Complete()
Obi.BurstJobHandle:Complete() (at Assets/Obi/Scripts/Common/Backends/Burst/BurstJobHandle.cs:20)
Obi.ObiUpdater:Substep(Single, Single, Int32) (at Assets/Obi/Scripts/Common/Updaters/ObiUpdater.cs:78)
Obi.ObiFixedUpdater:FixedUpdate() (at Assets/Obi/Scripts/Common/Updaters/ObiFixedUpdater.cs:50)
Reply
#18
(09-08-2022, 08:53 PM)snowtv Wrote: Thanks for the instructions!

I disabled the compilation and here is the error message:


Code:
IndexOutOfRangeException: Index 0 is out of range of '0' Length.
Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Collections.NativeArray`1[T].CheckElementReadAccess (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Collections.NativeArray`1[T].get_Item (System.Int32 index) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Obi.BurstDistanceConstraintsBatch+DistanceConstraintsBatchJob.Execute (System.Int32 i) (at Assets/Obi/Scripts/Common/Backends/Burst/Constraints/Distance/BurstDistanceConstraintsBatch.cs:101)
Unity.Jobs.IJobParallelForExtensions+ParallelForJobStruct`1[T].Execute (T& jobData, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at <2e6610ed29844f85a37924f81509fe5d>:0)
Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete(JobHandle&)
Unity.Jobs.JobHandle:Complete()
Obi.BurstJobHandle:Complete() (at Assets/Obi/Scripts/Common/Backends/Burst/BurstJobHandle.cs:20)
Obi.ObiUpdater:Substep(Single, Single, Int32) (at Assets/Obi/Scripts/Common/Updaters/ObiUpdater.cs:78)
Obi.ObiFixedUpdater:FixedUpdate() (at Assets/Obi/Scripts/Common/Updaters/ObiFixedUpdater.cs:50)

This means the particle indices you're passing to the distance constraints are incorrect, and the distance constraints are accessing non-existent particles.

Obi does not perform out of bounds checks at runtime, as that would be too expensive. In particular, the Oni backend does not perform any kind of checks, so out of bounds accesses result in undefined behavior (may crash, may cause heap corruption, all bets are off). The Burst backend relies on Unity's own safety system/debugger that will help you identify these issues, as happened here.

Upon further inspection, I see the particle indices you're passing to AttachParticlePairInColon() are hardcoded via the component's inspector. Since these values are all in the 900-1000 range, I'm guessing they're either vertex indices or actor indices, which seems to be incorrect since you're passing them to solver batches (unless I misunderstood something in your code). If they're were hardcoded solver indices, it wouldn't work either, because solver indices are not guaranteed to be the same across multiple executions of the scene so you cannot hardcode them.

When an actor gets added to a solver, a new index in the solver arrays for each actor particle is assigned. These indices (solver indices) can be different depending on the order in which actors get added, which is undefined (since the order in which Unity calls Awake(), Start() and other events for different objects is undefined):

Quote:You cannot specify the order in which an event function is called for different instances of the same MonoBehaviour subclass. For example, the Update function of one MonoBehaviour might be called before or after the Update function for the same MonoBehaviour on another GameObject — including its own parent or child GameObjects.

So it may work correctly, it may not work at all, it may result in completely different parts of your actors being sewn together.

There's an additional problem if you intend for these constraints to be persistent: as soon as you add a new actor to the solver, all constraints you've manually added to the solver will disappear, replaced with the ones in the actor's blueprints. Remember that adding a new actor to a solver calls SetConstraintsDirty(), and this triggers a replacement of all actor constraints with the ones stored in the blueprints.

All things considered, it looks like what you actually want is to add these constraints to the blueprints, not to the solver, because these constraints are not ephemeral but must be enforced over the entire object's lifetime. Will write an example for you asap.
Reply
#19
This code will permanently add the constraints to the actor's blueprint instance:

Code:
public void AttachParticlePairInColon(ObiTearableCloth colon, int colonMeshVertexA, int colonMeshVertexB)
    {
        ClothBlueprintParticleIndividualizer attacher = colon.GetComponent<ClothBlueprintParticleIndividualizer>();

        int particleIndexA = colon.clothBlueprint.topology.rawToWelded[colonMeshVertexA];
        int particleIndexB = colon.clothBlueprint.topology.rawToWelded[colonMeshVertexB];

        // get a hold of the distance constraint
        var distanceConstraints = colon.GetConstraintsByType(Oni.ConstraintType.Distance) as ObiConstraints<ObiDistanceConstraintsBatch>;

        // create a new distance constraints batch
        var batch = new ObiDistanceConstraintsBatch();

        // Add a constraint for the pair
        batch.AddConstraint(new Vector2Int(particleIndexA, particleIndexB), 0);

        // set the amount of active constraints in the batch to 2 (the ones we just added).
        batch.ActivateConstraint(0);

        // append the batch to the pin constraints:
        distanceConstraints.AddBatch(batch);

        colon.SetConstraintsDirty(Oni.ConstraintType.Distance);
    }

The only differences are that instead of getting a batch reference from the solver, I get it from the actor itself, and that the particle indices passed are actor indices. I see that the numbers in the inspector (topSeal and bottomSeal array) are mesh vertex indices, so I retrieve the particle indices from the topology's rawToWelded array (which maps vertex index to particle index).

At the end, call SetConstraintsDirty so that the solver knows a blueprint has been modified and it must reload distance constraints.
Reply
#20
(10-08-2022, 08:55 AM)josemendez Wrote: This means the particle indices you're passing to the distance constraints are incorrect, and the distance constraints are accessing non-existent particles.

Obi does not perform out of bounds checks at runtime, as that would be too expensive. In particular, the Oni backend does not perform any kind of checks, so out of bounds accesses result in undefined behavior (may crash, may cause heap corruption, all bets are off). The Burst backend relies on Unity's own safety system/debugger that will help you identify these issues, as happened here.

Upon further inspection, I see the particle indices you're passing to AttachParticlePairInColon() are hardcoded via the component's inspector. Since these values are all in the 900-1000 range, I'm guessing they're either vertex indices or actor indices, which seems to be incorrect since you're passing them to solver batches (unless I misunderstood something in your code). If they're were hardcoded solver indices, it wouldn't work either, because solver indices are not guaranteed to be the same across multiple executions of the scene so you cannot hardcode them.

When an actor gets added to a solver, a new index in the solver arrays for each actor particle is assigned. These indices (solver indices) can be different depending on the order in which actors get added, which is undefined (since the order in which Unity calls Awake(), Start() and other events for different objects is undefined):


So it may work correctly, it may not work at all, it may result in completely different parts of your actors being sewn together.

There's an additional problem if you intend for these constraints to be persistent: as soon as you add a new actor to the solver, all constraints you've manually added to the solver will disappear, replaced with the ones in the actor's blueprints. Remember that adding a new actor to a solver calls SetConstraintsDirty(), and this triggers a replacement of all actor constraints with the ones stored in the blueprints.

All things considered, it looks like what you actually want is to add these constraints to the blueprints, not to the solver, because these constraints are not ephemeral but must be enforced over the entire object's lifetime. Will write an example for you asap.

Thanks for the reply. You are correct that I hard-coded some vertex indices for the process. However, you can see that my method is looking up for the solver index for the particle that is closest to each of the vertex, then passing the particle indices to the AddConstraint().

Plus if my method is getting out of bound error, it doesn't make sense that you didn't encounter the same error on your side.

Is it possible to send a copy of the script modified by you?
Reply