[Action Required] Pivot API Release: Update F3X / SBS Plugins

will do, also how will the pivot points work
i have the beta feature enabled
but thanks for tell us this

1 Like

How can I simulate :PivotTo() function? Because I would like to test my game with couple testers. I already have attachments that act as Pivot points but I don’t know how to make a function that behaves like :PivotTo except that it takes attachment’s WorldCFrame. And I am very excited for the scripting API to be released in couple days so I can replace my Pivot attachments with actual Pivot points.

1 Like

Not quite sure what you’re asking for there, but I think this is what you want:

--[[see updated code below]]

Granted, this will only work for models that aren’t welded together (which I assume your stuff is not, because if it were you could just move it via a single .CFrame set)

2 Likes

My models are welded. Though I am unsure what you mean by “via a single .CFrame set”. Are you referring to MoveTo() function?

1 Like

Okay, code that will work if it’s welded as well:

local function PivotTo(root: PVInstance, currentPivot: CFrame, target: CFrame)
	local alreadyMovedAssemblies = {}
	local worldTransform = target * currentPivot:Inverse()
	for _, descendant in ipairs(root:GetDescendants()) do
		if descendant:IsA("BasePart") then
			local part = descendant :: BasePart
			local root = part:GetRootPart()
			if not alreadyMovedAssemblies[root] then
				alreadyMovedAssemblies[root] = true
				part.CFrame = worldTransform * part.CFrame	
			end
		end
	end
	if root:IsA("BasePart") then
		local part = root :: BasePart
		part.CFrame = worldTransform * part.CFrame
	end
end
3 Likes

Thank you so much for writing this awesome function for me. This could be also added to the PivotTo() documentation so people could see the equivalent function of this feature, basically a nice resource to help some understand how it works behind the scenes (a bit different) but still does same thing :wink:.

1 Like

That’s not a bad idea. The actual function is significantly more complicated since it includes the offset-caching to avoid floating point drift, but I could include a Lua version of it in the documentation page.

4 Likes

Is there any chance this functionality will extend to model/part resizing? I won’t be able to utilize any of this because objects in my game are cloned and uniformly resized based on CFrame+scale pairs. My game’s world is built assuming there is no performance bias for scales of 1, so objects are scaled freely. Rescaling models is extremely common in game engines, because it adds variety without needing more assets.

Some way to simultaneously CFrame and rescale uniformly would likely be the most performant. Part sizes could cache similarly to offsets. This could also potentially apply to sizeable values like Attachments or even ParticleEmitters, but it’s understandable if it only affects size for simplicity.

1 Like

It’s possible that there will be some first-class engine support for scaling of composite objects in the next round of package system changes, but unfortunately nothing yet.

1 Like

Alright great. Rescaling objects is very cheap in most engines. It’s currently pretty tedious to implement and not very performant to rescale models in Roblox.

Also, how much memory does offset caching use per-model? I’m curious how well it scales if I have hundreds of identical models. I’m hoping for features that allow our worlds to support more parts loaded in a scene overall. New properties like PivotOffset seem like they’re just going to make BaseParts less efficient over time. I would prefer lightweight objects over objects with feature bloat, especially if it means we can instantiate more before causing lag. I want to create a world filled with detail. PivotOffset seems like it’s useful in studio, but has little use at during run time.

Some way to create a prototype model, and create instances of it with specific scales/cframes would be the most performant I think. The prototype could have LOD info that gets generated, instead of calculating it for tens of thousands of potentially identical models spread across a huge game world.

1 Like

I think this is a really cool feature for people who actually build some different parts but for me, since I use many parts and when I select the entire thing it looks like a mess but otherwise I think it is a good feature. Maybe we should be allowed to customize pivots point like set transparency to it or something on the lines of that.

1 Like

Probably the best feature of this API honestly.

1 Like

Will there be a tutorial for new users for the Onboarding experience? This is a pretty big update and may confuse some newer developers.

1 Like

Not very performant is an understatement, it should be avoided at all costs.

A lot, since it’s using the most stable approach to do this, which is completely unopinionated about what’s going on with the models in your level. Specifically, it needs to temporarily store two extra CFrames per part in any of the models that you call PivotTo on.

That’s the reason I did not backport the offset caching behavior to MoveTo / SetPrimaryPartCFrame, because it has a non-negligible cost. The next round of package system changes that I mentioned above will give me an opportunity to reduce that cost significantly but only on models which are packages.

It may not seem like PivotOffset is very useful right now, but once we make the Mesh importers set PivotOffset = mesh origin for MeshParts it will be extremely important in mesh based modeling workflows.

But overall there’s no easy answer to this, compounded by the fact that there is no “in studio” right now: Your place is your place whether it’s in studio or in-game, with no processing step in-between them.

I’ve been thinking about this problem too, of how to reduce the part overhead, and I don’t think adding properties that have good value is doing irreparable damage in any way: There’s lots of things we could do in the future to introspect what usage patterns your game is actually performing and optimize the parts for those for instance, and that’s just one option.

2 Likes

I don’t know if we’ll have a page in the onboarding document initially, but we will have a detailed page on how pivot works in the DevHub documentation beyond simply the documentation on the API methods.

1 Like

Does this mean that setting part.CFrame has the additional overhead of checking to clear this cache?

This still seems like a studio-only convenience that could be achieved using something like Attributes. While these features may be convenient when building, but I don’t think it’s worth it if they impact performance outside of studio. Even if it seems relevant to something like avatar packages, it’s still not relevant to what a BasePart actually is because this affects all parts in the worlds we create.

My perspective relates this to properties like part.FormFactor, part.Locked, as well as part surface types. These properties are just conveniences for building, and can start to hurt performance outside of building-centric environments as they accumulate up due to feature bloat. Experiences we create are always going to push the limits of how many parts are possible on both high and low end hardware, and these properties don’t help.

My projects have always had various setup / compile stages when the game first runs, mainly to process models and clear properties and objects that are only needed in studio. I don’t think I’m the only one. Currently I run them before publishing

Alright that’s good to hear. I suppose I’m mainly worried about whether setting part.CFrame will be slower because it needs to clear the PivotTo cache.

Perhaps building-related properties (Locked, PivotOffset, LeftSurface , LeftSurfaceInput , LeftParamA , LeftParamB , RightSurface , RightSurfaceInput , RightParamA , RightParamB , TopSurface , TopSurfaceInput , TopParamA , TopParamB , BottomSurface , BottomSurfaceInput , BottomParamA , BottomParamB , FrontSurface , FrontSurfaceInput , FrontParamA , FrontParamB , BackSurface , BackSurfaceInput , BackParamA , BackParamB) could eventually use the attribute system internally with non-alphanumeric keys, or something similar. I remember hearing something like this is done for surfaces (where they collectively use 1 byte by default), but this way there’s no memory impact on parts that don’t use them.

No, that’s why it needs two extra CFrames, so that the cost of the offset caching can be totally isolated to the PivotTo call itself. (It stores where it thinks the part was, and what it thinks the offset is, so that it can lazily tell if something else moved the part and the cached offset is invalid)

Yes… but the point is, doing something like that is not a requirement / core part of how deploying a game works right now, and it’s not something that we want to make a part of the normal process either. The fact that code can generally work the same regardless of whether it’s running in studio or a live game is something really powerful about Roblox that we aren’t planning to give up.

There’s quite a few reasons that using the attribute system is undesirable for this, but something similar to the attribute system is one way that this could be solved, yes.

1 Like

Thanks for helping me understand. It seems like a good implementation that doesn’t affect the performance of other features.

I completely agree, so long as building-centric properties don’t affect the performance of instances that don’t use them and don’t bloat the API page too much.

Understandable. My reasoning was that multiple expandable structures might use slightly more memory for cases that don’t use either of them, which is relevant to all inert / legacy properties (not just for BasePart) where access speed isn’t a priority.

It would, but there’s some very large benefits to not using attributes for that, for instance:

  • Network replication would have to be broken down into multiple different codepaths for Attributes because you would not want to double-replicate changes to Attribute backed properties.

  • Attributes can be added to an object, but also removed. This comes at a cost of using a data structure that can support this. Infrequently used properties would rather be backed by a data structure that you can only add items to which would let it be smaller and faster.

  • It would be a leaky abstraction where you could cheat and look at the attributes backing the properties without really making the code jump through some hoops.

1 Like

The APIs are tentatively live.

You can check that your places are working with them enabled, but please hold for a few hours on publishing live code that relies on the APIs in case something goes wrong and we have to turn them back off.

1 Like