public List <Partition> GetPartitions(
            CollisionPointStructure[] collisionPoints,
            List <IConstraint> joints,
            IShape[] shapes,
            ISoftShape[] softShapes)
        {
            List <SpatialPartition> spatialPartitions = CalculateSpatialPartitioning(collisionPoints, joints, shapes);

            List <Partition> partitions = new List <Partition>();

            if (spatialPartitions != null)
            {
                HashSet <int> totObjectIndex = new HashSet <int>();

                for (int i = 0; i < spatialPartitions.Count; i++)
                {
                    Partition     partitionItem = new Partition();
                    HashSet <int> objectIndex   = new HashSet <int>();

                    for (int j = 0; j < spatialPartitions[i].ObjectList.Count; j++)
                    {
                        if (spatialPartitions[i].ObjectList[j].Type == ContactGroupType.Collision)
                        {
                            CollisionPointStructure cpStruct = ConstraintHelper.Find(
                                collisionPoints,
                                spatialPartitions[i].ObjectList[j]);

                            if (cpStruct != null)
                            {
                                partitionItem.PartitionedCollisionPoints.Add(cpStruct);
                            }

                            objectIndex.Add(cpStruct.ObjectIndexA);
                            objectIndex.Add(cpStruct.ObjectIndexB);
                            totObjectIndex.Add(cpStruct.ObjectIndexA);
                            totObjectIndex.Add(cpStruct.ObjectIndexB);
                        }
                        else
                        {
                            IConstraint smJoint = joints.Find(item =>
                                                              item.GetObjectIndexA() == spatialPartitions[i].ObjectList[j].IndexA &&
                                                              item.GetObjectIndexB() == spatialPartitions[i].ObjectList[j].IndexB &&
                                                              item.GetKeyIndex() == spatialPartitions[i].ObjectList[j].KeyIndex);

                            partitionItem.PartitionedJoints.Add(smJoint);

                            objectIndex.Add(smJoint.GetObjectIndexA());
                            objectIndex.Add(smJoint.GetObjectIndexB());
                            totObjectIndex.Add(smJoint.GetObjectIndexA());
                            totObjectIndex.Add(smJoint.GetObjectIndexB());
                        }
                    }

                    ////Add Soft Body Constraints if is involved in collision
                    foreach (var item in objectIndex)
                    {
                        if (shapes[item] is ISoftShape softShape)
                        {
                            partitionItem.PartitionedJoints.AddRange(softShape.SoftConstraint);
                        }
                    }

                    partitions.Add(partitionItem);
                }

                ////Add Soft Body Constraints if is not involved in collision
                foreach (var item in softShapes)
                {
                    if (!totObjectIndex.Contains(((IShape)item).ID))
                    {
                        Partition partitionItem = new Partition();
                        partitionItem.PartitionedJoints.AddRange(item.SoftConstraint);
                        partitions.Add(partitionItem);
                    }
                }
            }
            else if (softShapes.Length > 0)
            {
                foreach (var softShape in softShapes)
                {
                    Partition partitionItem = new Partition();
                    partitionItem.PartitionedJoints.AddRange(softShape.SoftConstraint);
                    partitions.Add(partitionItem);
                }
            }

            return(partitions);
        }