Posts: 6,348
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
07-09-2022, 10:10 AM
(This post was last modified: 07-09-2022, 10:11 AM by josemendez.)
(07-09-2022, 10:04 AM)Anna7777 Wrote: Hi. One more question is it possible to optimize that balloon softbody for mobile devices? Because now I have very poor performance on them.
Which simulation backend are you using? Burst generally performs a lot better on mobile.
If you're already using Burst, try focusing on reducing the amount of particles (resolution) and the amount of substeps.
Posts: 27
Threads: 6
Joined: Jul 2022
Reputation:
0
(24-06-2022, 07:36 AM)josemendez Wrote: Btw, there's a known bug in vertex surface sampling. Replace the Initialize() method in Obi/Scripts/Softbody/Blueprints/ObiSoftbodySurfaceBlueprint.cs with this:
Code: protected override IEnumerator Initialize()
{
if (inputMesh == null || !inputMesh.isReadable)
{
Debug.LogError("The input mesh is null, or not readable.");
yield break;
}
ClearParticleGroups();
// Prepare candidate particle arrays:
List<Vector3> particlePositions = new List<Vector3>();
List<Vector3> particleNormals = new List<Vector3>();
// Prepare constraint arrays:
particleIndices = new List<int>();
constraintIndices = new List<int>();
// Transform mesh data:
blueprintTransform = Matrix4x4.TRS(Vector3.zero, rotation, scale);
Vector3[] vertices = inputMesh.vertices;
Vector3[] normals = inputMesh.normals;
int[] tris = inputMesh.triangles;
Bounds transformedBounds = new Bounds();
for (int i = 0; i < vertices.Length; ++i)
{
vertices[i] = blueprintTransform.MultiplyPoint3x4(vertices[i]);
transformedBounds.Encapsulate(vertices[i]);
}
for (int i = 0; i < normals.Length; ++i)
normals[i] = Vector3.Normalize(blueprintTransform.MultiplyVector(normals[i]));
// initialize arrays:
particleType = new List<ParticleType>();
//voxelize for cluster placement:
var voxelize = VoxelizeForShapeAnalysis(transformedBounds.size);
while (voxelize.MoveNext()) yield return voxelize.Current;
//voxelize for surface:
voxelize = VoxelizeForSurfaceSampling(transformedBounds.size);
while (voxelize.MoveNext()) yield return voxelize.Current;
if (surfaceSamplingMode == SurfaceSamplingMode.Voxels)
{
var surface = VoxelSampling(surfaceVoxelizer, particlePositions, particleNormals, MeshVoxelizer.Voxel.Boundary, ParticleType.Surface);
while (surface.MoveNext()) yield return surface.Current;
IEnumerator ip = InsertParticlesIntoVoxels(surfaceVoxelizer, particlePositions);
while (ip.MoveNext()) yield return ip.Current;
IEnumerator vc = CreateClustersFromVoxels(surfaceVoxelizer, particlePositions, VoxelConnectivity.Faces | VoxelConnectivity.Edges, new List<ParticleType>(){ParticleType.Surface});
while (vc.MoveNext()) yield return vc.Current;
for (int i = 0; i < particlePositions.Count; ++i)
particlePositions[i] = ProjectOnMesh(particlePositions[i], vertices, tris);
}
else if (surfaceSamplingMode == SurfaceSamplingMode.Vertices)
{
var sv = VertexSampling(vertices, particlePositions);
while (sv.MoveNext()) yield return sv.Current;
// map vertices to particles:
var mp = MapVerticesToParticles(vertices, particlePositions);
while (mp.MoveNext()) yield return mp.Current;
var ss = SurfaceMeshShapeMatchingConstraints(particlePositions,tris);
while (ss.MoveNext()) yield return ss.Current;
}
if (volumeSamplingMode == VolumeSamplingMode.Voxels)
{
// sample the volume of the mesh:
voxelize = VoxelizeForVolumeSampling(transformedBounds.size);
while (voxelize.MoveNext()) yield return voxelize.Current;
var volume = VoxelSampling(volumeVoxelizer, particlePositions, particleNormals, MeshVoxelizer.Voxel.Inside, ParticleType.Volume);
while (volume.MoveNext()) yield return volume.Current;
var ip = InsertParticlesIntoVoxels(volumeVoxelizer, particlePositions);
while (ip.MoveNext()) yield return ip.Current;
var vc = CreateClustersFromVoxels(volumeVoxelizer, particlePositions, VoxelConnectivity.Faces, new List<ParticleType>() { ParticleType.Volume });
while (vc.MoveNext()) yield return vc.Current;
vc = CreateClustersFromVoxels(volumeVoxelizer, particlePositions, VoxelConnectivity.All, new List<ParticleType>() { ParticleType.Volume | ParticleType.Surface });
while (vc.MoveNext()) yield return vc.Current;
// map vertices to particles:
var mp = MapVerticesToParticles(vertices, particlePositions);
while (mp.MoveNext()) yield return mp.Current;
}
// sample skeleton:
var sk = SkeletonSampling(transformedBounds.size, particlePositions, particleNormals);
while (sk.MoveNext()) yield return sk.Current;
// create skeleton clusters:
if (skeleton != null)
{
var sc = CreateClustersFromSkeleton(particlePositions);
while (sc.MoveNext()) yield return sc.Current;
}
// generate particles:
var generate = GenerateParticles(normals, particlePositions, particleNormals);
while (generate.MoveNext()) yield return generate.Current;
// generate shape matching constraints:
IEnumerator bc = CreateShapeMatchingConstraints(particlePositions);
while (bc.MoveNext()) yield return bc.Current;
generatedMesh = inputMesh;
}
Would you be able to sticky this code somewhere / put it somewhere more easily found?
Posts: 6,348
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
08-11-2022, 07:43 AM
(This post was last modified: 08-11-2022, 07:45 AM by josemendez.)
(08-11-2022, 06:21 AM)danazoid Wrote: Would you be able to sticky this code somewhere / put it somewhere more easily found?
Hi danazoid!
This has been fixed on 6.5, also a few improvements to the blueprint editor have been made. Updating should be the preferred solution. Let me know if you'd prefer to stay on 6.4 or if you'd want this code pinned publicly for some other reason.
kind regards,
|