[Studio Beta] Solid Modeling on Meshes & new Fragment and Sweep APIs

Could someone tell me what is this task? It appears frequently in my game and I make strong use of the fragment API. The fragment API is actually very fast, however this task alone dominates my runtime cost by a massive gap and it happens I think after the first query the fragmented parts are added in? I could be wrong on that though but if I try doing a query after they are the assemble task suddenly appears under that query instead.

Should I file a bug report for the physics team?

Update - I identified that the NOUSignals was a task that had to do with networking using ImprovedPhysicsReplication. What’s odd though is that these were clientside parts. No engine physics networking was required here. Disabling this seem to reduce the cost down by a significant margin and I no longer see the NOU signals task.

local userInputService = game:GetService('UserInputService')
local GeometryService = game:GetService('GeometryService')
local players = game:GetService('Players')
local localPlayer = players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local children = character:GetChildren('BasePart')

local function onFragment()
	local sites = GeometryService:GenerateFragmentSites(children)
	
	local success, fragments = pcall(function()
		return GeometryService:CreateFragment(children, sites)
	end)
	if success and fragments then
		for _, item in fragments do
			local instance = item.Instance
			instance.Parent = workspace
		end
	end
end


local function onInputBegan(input, gameProcessedEvent)
	
	if gameProcessedEvent then return end
	
	if input.KeyCode == Enum.KeyCode.U then
		onFragment()
	end
	
end

What did I do wrong

put a statement to check if success is false and warn with the error. you should do that every time you use a pcall. you are using the wrong name for the fragment the function name is not :CreateFragment()

Check this link out for code examples. Its a pretty complex API

local userInputService = game:GetService('UserInputService')
local geometryService = game:GetService('GeometryService')
local players = game:GetService('Players')
local localPlayer = players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local children = character:GetChildren('BasePart')

local function onFragment()
	local sites = geometryService:GenerateFragmentSites(children)

	local success, fragments = pcall(function()
		return geometryService:FragmentAsync(children, sites)
	end)
	
	if success and fragments then
		for _, item in fragments do
			local instance = item.Instance
			instance.Parent = character
		end
	else
		 warn('broken')
	end
end


local function onInputBegan(input, gameProcessedEvent)

	if gameProcessedEvent then return end

	if input.KeyCode == Enum.KeyCode.U then
		onFragment()
	end

end

It still didn’t work, this script is in a LocalScript in StarterCharacterScripts in StarterPlayer

Is it my code or the FragmentAsync doesn’t support a group of BasePart?
Will FragmentAsync be improved to support a group of BasePart or should I make a loop that detects each BasePart inside a character except for HumanoidRootPart

local userInputService = game:GetService('UserInputService')
local geometryService = game:GetService('GeometryService')
local players = game:GetService('Players')
local localPlayer = players.LocalPlayer
local character = localPlayer.Character or localPlayer.CharacterAdded:Wait()
local children = character:GetChildren('BasePart')

local function onFragment()
	local sites = geometryService:GenerateFragmentSites(children)

	local success, fragments = pcall(function()
		return geometryService:FragmentAsync(children, sites)
	end)
	
	if success and fragments then
		for _, item in fragments do
			local instance = item.Instance
			instance.Parent = workspace
		end
	else
		 warn('broken')
	end
end


local function onInputBegan(input, gameProcessedEvent)

	if gameProcessedEvent then return end

	if input.KeyCode == Enum.KeyCode.U then
		onFragment()
	end

end

userInputService.InputBegan:Connect(onInputBegan)

im getting some unexpected frame drop with meshpart tool csg on all baseparts I think this says its being called on the foreground? This is running my frametime up. Is it reading the same tool over and over again or does this have to do with converting the prims to meshparts? If its reading the same tool over and over again could it just be cached? I dont get this spike when doing a prim on mesh op so I suspect its just reading the same tool every time. The meshpart im using is like 40 tris too so does reading it actually take nearly 2 ms of compute or does it need to go through some fetching?

Also unrelated but im confused, I am seeing many csg operations being done on different threads on the background. Is this a new feature? I only saw this with mesh CSG

What is this task it is causing frequent game crashes on scenes with lots of parts (like more than 10k). It occurs after solid modeling. It does not cause crashes in studio. Are you guys aware of this and should I get a repro?

Hey! Thanks for reporting this, I was not aware of either of these issues. It is hard to tell what is causing either of the two issues. Regarding the slow BaseParts, AFAICT from the screenshot a lot of meshes are being deserialized. Certainly would be super helpful to have a repro file that I can check out!

Sorry I’ll see if I cant get that to you this weekend its been a busy week for me and Im still not sure what the cause is but Im thinking it something to do with clientside CSG.

But whats the timeline for getting the csg meshpart darkening and false culling bug fixed? I really need that fixed soon because its a major bug and it practically makes doing csg on any kind of meshpart not possible for me because it all just turns super dark and flashes which looks bad.

Sorry about those two things not being fixed yet. I am not sure I can give a specific timeline, but I’ll try to work on fixing the darkening bug this week and I’ll look into finding someone who can look into the culling issue.

If it helps it looked like the culling was using the parts position only and not its aabb for both frustrum and occlusion which was making that odd flicker. Not sure why it was doing this though but when I used only fragments I didnt see the problem but when I started doing negates on those fragments (Meshparts) the issue emerged.

1 Like

Will FragmentAsync support BaseParts in Model instead of one BasePart

Hey! Can you give more details what you are looking for? Of course you can use the API to destruct any BasePart inside a model, but it sounds like you are looking for smth more convenient?

Can we get a way to preload meshes by their ids or something? I know you guys had a preload method at one point but I believe that was removed for some reason. In my game I have a lot of duplicate meshes that take a long time to destroy for their first operations. After the first operation though subsequent operations are fast.

I’m not entirely sure how your internal pipeline works but I think It would be nice if at all possible if we could have a way preload mesh IDs since before they are destroyed they all should have the same content if Im not mistaken. I’d imagine you could do a similar thing with union instances too. Regardless having a way to do this without needing to do a empty csg operation like what you had in your demo would be very handy.

can we get a fix for show decomposition goemetry on meshparts created by csg rn it just renders as box

A way to set the fragment collision fidelity only (and not exterior parts) might be useful for the fragment method. I am running into physics issues with lots of fragments and using a bounding box approximation might be handy for lower powered devices. I tried welding a box onto each part but thats laggy hacky and not memory efficient

Thanks for the feedback! I think I know why the convex decomp is not showing, I’ll look into that. Regarding the preload, you can preload a mesh or union by subtracting a box that doesn’t intersect the mesh. We removed the API that we had in the early alpha since it can be emulated using existing APIs and we wanted to keep things simple. An option to set the collision fidelity specifically for the fragments also makes sense and we have discussed this internally. I appreciate the feedback and I’ll bring this up to the team!

I was just looking into this and I am not seeing any darkening happening. The only color issue I am seeing is if you fracture an empty mesh part (i.e. no mesh content) it darkens. I’ve merged a fix for this, but I am not sure this is what you were referring to. If you have a specific repro that you want me to try, let me know.

yeah it happens in my game when you mix negate operations and fragments. Should I just give you that or do you want like a minimal reproducible file sorta thing? Im not exactly sure whats best. The ladder might take me a bit of time

Can you tell me what the initial input type is (i.e. union, mesh part or just a part). Also just to clarify, when you say negate, I assume you mean you are using GeometryService:SubtractAsync, is that correct? Repro would be ideal, but I can also try to repro myself if you give some more information.