When moving a large group of parts on a render step, it can be optimal to use: workspace:BulkMoveTo(parts: {BasePart}, cframes: {CFrame})
I’m requesting the addition of: workspace:BulkPivotTo(objects: {PVInstance}, cframes: {CFrame})
which does the same thing but applies :PivotTo(cf) instead of .CFrame = cf
In PS99 we commonly need to move many models every render step (balloon models, for example.) Currently to accomplish this, I can iterate and use :PivotTo(cf) or I can build an object/cframe table of the descendants of the model, finding the descendants’ offsets from the model’s pivot along the way, and use BulkMoveTo. The former isn’t ideal because it crosses the Lua/C boundary quite a bit and thus is slow. BulkMoveTo also isn’t optimal because I need to build a potentially large set of arrays, also crossing the C boundary a lot. And frankly it’s just annoying to do. BulkPivotTo would be a great addition to the engine.
Just FYI: A BulkPivotTo would potentially be slower than your current BulkMoveTo solution. You’re able to make assumptions about the setup of parts / when things have changed requiring invalidation with a BulkMoveTo solution which BulkPivotTo would not be able to make (resulting in worse perf). Furthermore you could consider using BulkMoveTo on the root part of models connected with joints so that you don’t have to compute any offsets.
Do you think you could construct a representative benchmark to share? I could experiment a bit with how the perf compares between the three approaches.
But I suspect that the API lies in too awkward a spot to make sense: Too complex for people who just want their thing to work and slow enough compared to an optimal BulkMoveTo solution that people squeezing the full perf out of something don’t want to use it.
I have done tests, and using PivotTo is slower than changing the CFrame of the model’s rootpart (both with a properly welded model, using PivotTo on an unwelded model is really bad)
From what I remember, changing the CFrame of the model’s rootpart on a welded model is slower than doing it on a normal part, but nowhere as slow as doing it for every individual part of the model
I do not have performance numbers though, as I have done the tests a while ago and didn’t save the results, I just wanted to see which one was the fastest
I use BulkMoveTo to move many models and it works great. Not a lot of people know that works (same with using TweenService on the model’s RootPart. Maybe this could be added in the documentation if not already?)
This! My game currently has guns which can shoot about 120 bullets / second, and while ~60% of this computational power is for raycasts alone, I notice that 30-40% of the time taken is calling PivotTo on each bullet per frame. These bullets have CanCollide, CanTouch and CanQuery all disabled and are used purely visually without interacting with anything.
I implemented a system that works with WorldRoot:BulkMoveTo, but I realized that all of this effort to optimize was useless because BulkMoveTo does not preserve rotation, unlike a BulkPivotTo method would. I used BulkMoveTo in one of my chunk loading systems because it was much MUCH faster than CFraming every object whenever the character moved around.
For now, I’ll unfortunately have to go back to mass calling PivotTo and see about cranking back the update rate.
Not sure what you mean by “Doesn’t preserve rotation”? Do you mean doesn’t take the PivotOffset of the parts into account?
Because you can absolutely rotate stuff with BulkMoveTo, all it’s doing internally is a bunch of partArray[i].CFrame = valueArray[i], there’s no complicated logic involved.