Lets say if I need to offset vertices of mesh by Vector3(3.0f, 3.0f, 3.0f), rotate them by 30 degrees in x axis and scale them by Vector3(2f, 2f, 2f), what would be the most efficient way?
I have static class which holds multiple meshes (Loaded from resources), and I need to add them to main mesh and apply to them different positions, rotations and scaling.
This is my solution so far: It looks quite uneffective, and I have no idea how to do rotations.
public static Vector3[] TransformMesh(Mesh mesh, Vector3 position, Quaternion rotation, Vector3 scale)
{
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] = Vector3.Scale(vertices[i], scale) + position;
}
return vertices;
}
Iām not sure to understand what you are trying to do here.
Do you really have to manipulate mesh vertices, or could you have a GameObject that hold a mesh as one of itās component, giving you the ability to easily manipulate it (rotation, scale, positionā¦) So you would end up with a hierarchy of gameobject, having each one a meshRenderer.
Or do you really need to have one final mesh (for optimization purpose maybe) ?
āI have static class which holds multiple meshes (Loaded from resources), and I need to add them to main mesh and apply to them different positions, rotations and scaling.ā
So iām not sure of what is your final goal again, but it makes me think of having something like a terrain, and instanciating objects on it (like rocks or tree) in random position / rotation. If it is the case than you should probably create a bunch of prefab with your different meshes, and manipulate gameObjects.
But again, I donāt know what you are trying to achieve so thiis may be totally irrelevant ^^
Assuming you have each mesh as a separate object, I think you could simply apply different position, rotation, and scaling on each object by using the objectās transform. Then, when everything is in place, combine them with the CombineMeshes function.
Its going to be building system and I am very concerned about performance and mainly I hate using monobehaviours for global constants.
Meshes should be avaible to all scenes, and should load at certain time. I am not using gameobjects for this, as I guess I canāt instantiate gameobjects on separate thread (So far with my system I can handle 1 mil cubes at once without problems).
Everything works, but I have no clue what to do about rotations.
Have you tested it to prove it is faster than your previous code? I really doubt it because scale + translate is just 3 multiplications and 3 additions, while matrix4x4 multiplication involves 64 multiply ops and 48 adds. You might gain much more performance writing non-allocating version of your code. And more, if youāll just combine those meshes as is and scale+translate your vertices using vertex shader. You may use additional shader channels to pass scale and translation vectors along with vertices.
I guess using sin and cos would be less effective than using matrix multiplications? Anyway, I measured matrix multiplication for 1 000 000 vertices, and I guess this will do. Sorry if I was not clear what I was asking for, I basically wanted to find way how to rotate vertex, and if possible, use some fancy function, that is already built into unity.
Sine/cosine are not that hard to compute, see here Computing Trigonometric Functions Moreover, modern cpus and gpus use trigonometric tables to calculate results even faster. And you should know what using Matrix4x4.TRS already includes trigonometric calculations bot sin and cos for all rotation angles. So I think your guess is wrong. Looks like the fastest way it tio combine meshes as they are, send them to the GPU along with transformation data and transform vertices on GPU using simple formulas without matrix multiplication.
Oh, I see. You are right, I was somehow thinking that I would need to recalculate trigonometric functions for every vertex, instead I should do it only once for mesh. Thanks for your patience, I will definitively try this.
If you need CPU matrix multiply - set up the matrices before transformation and do your (hopefully parallel) transformations through that matrix on the input vertices / normals. Use Matrix4x4.TRS as commented in earlier posts.
Donāt listen to anyone saying āsin and cosā arenāt expensive. They are pissing in your pocket and telling you itās raining. They are expensive. If you can not use them - donāt. Unity has helper functions for this purpose.
If there are enough vertices in the mesh / cluster - use a compute shader - if your platform(s) allow for it. When you are doing generic transformations on data that can be parallelized - consider compute shaders - for almost anything you want to accelerate. You will win.