Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 3 additions & 78 deletions Core/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Make = require(Tool.Libraries.Make)
local Roact = require(Tool.Vendor:WaitForChild 'Roact')
local Maid = require(Tool.Libraries:WaitForChild 'Maid')
local Cryo = require(Tool.Libraries:WaitForChild('Cryo'))
local JointUtils = require(Tool.Libraries:WaitForChild("JointUtils"))

-- References
Support.ImportServices();
Expand Down Expand Up @@ -960,84 +961,8 @@ function ToggleSwitch(CurrentButtonName, SwitchContainer)
end;
end;

-- References to reduce indexing time
local GetConnectedParts = Instance.new('Part').GetConnectedParts;
local GetChildren = script.GetChildren;

function GetPartJoints(Part, Whitelist)
-- Returns any manual joints involving `Part`

local Joints = {};

-- Get joints stored inside `Part`
for Joint, JointParent in pairs(SearchJoints(Part, Part, Whitelist)) do
Joints[Joint] = JointParent;
end;

-- Get joints stored inside connected parts
for _, ConnectedPart in pairs(GetConnectedParts(Part)) do
for Joint, JointParent in pairs(SearchJoints(ConnectedPart, Part, Whitelist)) do
Joints[Joint] = JointParent;
end;
end;

-- Return all found joints
return Joints;

end;

-- Types of joints to assume should be preserved
local ManualJointTypes = Support.FlipTable { 'Weld', 'ManualWeld', 'ManualGlue', 'Motor', 'Motor6D' };

function SearchJoints(Haystack, Part, Whitelist)
-- Searches for and returns manual joints in `Haystack` involving `Part` and other parts in `Whitelist`

local Joints = {};

-- Search the haystack for joints involving `Part`
for _, Item in pairs(GetChildren(Haystack)) do

-- Check if this item is a manual, intentional joint
if ManualJointTypes[Item.ClassName] and
(Whitelist[Item.Part0] and Whitelist[Item.Part1]) then

-- Save joint and state if intentional
Joints[Item] = Item.Parent;

end;

end;

-- Return the found joints
return Joints;

end;

function RestoreJoints(Joints)
-- Restores the joints from the given `Joints` data

-- Restore each joint
for Joint, JointParent in pairs(Joints) do
Joint.Parent = JointParent;
end;

end;

function PreserveJoints(Part, Whitelist)
-- Preserves and returns intentional joints of `Part` connecting parts in `Whitelist`

-- Get the part's joints
local Joints = GetPartJoints(Part, Whitelist);

-- Save the joints from being broken
for Joint in pairs(Joints) do
Joint.Parent = nil;
end;

-- Return the joints
return Joints;

end;
Core.PreserveJoints = JointUtils.PreserveJoints
Core.RestoreJoints = JointUtils.RestoreJoints

-- Initialize the UI
InitializeUI();
Expand Down
72 changes: 72 additions & 0 deletions Libraries/JointUtils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
--!strict

type DisabledJointSnapshot = {
disabledJoints: {JointInstance},
initialPart0CFrame: {[JointInstance]: CFrame},
initialPart1CFrame: {[JointInstance]: CFrame},
anchoredParts: {BasePart},
}

local JointUtils = {}

function JointUtils.RestoreJoints(jointSnapshot: DisabledJointSnapshot)
for _, joint in jointSnapshot.disabledJoints do
if not (joint.Part0 and joint.Part1) then
continue
end

local initialOffset = jointSnapshot.initialPart0CFrame[joint]:ToObjectSpace(jointSnapshot.initialPart1CFrame[joint])
local newOffset = joint.Part0.CFrame:ToObjectSpace(joint.Part1.CFrame)
local didJointChange = (initialOffset ~= newOffset)
if didJointChange then
local didPart0Change = joint.Part0.CFrame ~= jointSnapshot.initialPart0CFrame[joint]
local didPart1Change = joint.Part1.CFrame ~= jointSnapshot.initialPart1CFrame[joint]
if didPart0Change then
joint.C0 = joint.Part0.CFrame:ToObjectSpace(joint.Part1.CFrame:ToWorldSpace(joint.C1))
end
if didPart1Change then
joint.C1 = joint.Part1.CFrame:ToObjectSpace(joint.Part0.CFrame:ToWorldSpace(joint.C0))
end
end
joint.Enabled = true
end
for _, part in jointSnapshot.anchoredParts do
part.Anchored = false
end
end

function JointUtils.PreserveJoints(part: BasePart): DisabledJointSnapshot
local initialPart0CFrame: {[JointInstance]: CFrame} = {}
local initialPart1CFrame: {[JointInstance]: CFrame} = {}
local disabledJoints: {JointInstance} = {}
local anchoredParts: {BasePart} = {}

for _, joint in part:GetJoints() do
if not (joint:IsA("JointInstance") and joint.Enabled and joint.Part0 and joint.Part1) then
continue
end

joint.Enabled = false
table.insert(disabledJoints, joint)
initialPart0CFrame[joint] = joint.Part0.CFrame
initialPart1CFrame[joint] = joint.Part1.CFrame

if not joint.Part0.Anchored then
table.insert(anchoredParts, joint.Part0)
joint.Part0.Anchored = true
end
if not joint.Part1.Anchored then
table.insert(anchoredParts, joint.Part1)
joint.Part1.Anchored = true
end
end

return {
disabledJoints = disabledJoints,
initialPart0CFrame = initialPart0CFrame,
initialPart1CFrame = initialPart1CFrame,
anchoredParts = anchoredParts,
}
end

return JointUtils
99 changes: 12 additions & 87 deletions SyncAPI.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Security = require(Tool.Core.Security);
RegionModule = require(Tool.Libraries.Region);
Support = require(Tool.Libraries.SupportLibrary);
Serialization = require(Tool.Libraries.SerializationV3);
local JointUtils = require(Tool.Libraries.JointUtils)

-- Import services
Support.ImportServices();
Expand Down Expand Up @@ -459,15 +460,14 @@ Actions = {

-- Preserve joints
for Part, Change in pairs(PartChangeSet) do
Change.Joints = PreserveJoints(Part, PartChangeSet)
Change.Joints = JointUtils.PreserveJoints(Part)
end;

-- Perform each change
for Part, Change in pairs(PartChangeSet) do

-- Stabilize the parts and maintain the original anchor state
Part.Anchored = true;
Part:BreakJoints();
Part.Velocity = Vector3.new();
Part.RotVelocity = Vector3.new();

Expand All @@ -491,8 +491,8 @@ Actions = {

-- Restore the parts' original states
for Part, Change in pairs(PartChangeSet) do
Part:MakeJoints();
RestoreJoints(Change.Joints);
JointUtils.RestoreJoints(Change.Joints)
Part:MakeJoints()
Part.Anchored = Change.InitialState.Anchored;
end;

Expand Down Expand Up @@ -531,12 +531,15 @@ Actions = {
end;
end;

for Part, Change in pairs(ChangeSet) do
Change.Joints = JointUtils.PreserveJoints(Part)
end

-- Perform each change
for Part, Change in pairs(ChangeSet) do

-- Stabilize the parts and maintain the original anchor state
Part.Anchored = true;
Part:BreakJoints();
Part.Velocity = Vector3.new();
Part.RotVelocity = Vector3.new();

Expand All @@ -559,6 +562,7 @@ Actions = {

-- Restore the parts' original states
for Part, Change in pairs(ChangeSet) do
JointUtils.RestoreJoints(Change.Joints)
Part:MakeJoints();
Part.Anchored = Change.InitialState.Anchored;
end;
Expand Down Expand Up @@ -609,15 +613,14 @@ Actions = {

-- Preserve joints
for Part, Change in pairs(PartChangeSet) do
Change.Joints = PreserveJoints(Part, PartChangeSet)
Change.Joints = JointUtils.PreserveJoints(Part)
end;

-- Perform each change
for Part, Change in pairs(PartChangeSet) do

-- Stabilize the parts and maintain the original anchor state
Part.Anchored = true;
Part:BreakJoints();
Part.Velocity = Vector3.new();
Part.RotVelocity = Vector3.new();

Expand All @@ -641,8 +644,8 @@ Actions = {

-- Restore the parts' original states
for Part, Change in pairs(PartChangeSet) do
Part:MakeJoints();
RestoreJoints(Change.Joints);
JointUtils.RestoreJoints(Change.Joints)
Part:MakeJoints()
Part.Anchored = Change.InitialState.Anchored;
end;

Expand Down Expand Up @@ -1759,84 +1762,6 @@ function GetPartsFromSelection(Selection)
return Parts
end

-- References to reduce indexing time
local GetConnectedParts = Instance.new('Part').GetConnectedParts;
local GetChildren = script.GetChildren;

function GetPartJoints(Part, Whitelist)
-- Returns any manual joints involving `Part`

local Joints = {};

-- Get joints stored inside `Part`
for Joint, JointParent in pairs(SearchJoints(Part, Part, Whitelist)) do
Joints[Joint] = JointParent;
end;

-- Get joints stored inside connected parts
for _, ConnectedPart in pairs(GetConnectedParts(Part)) do
for Joint, JointParent in pairs(SearchJoints(ConnectedPart, Part, Whitelist)) do
Joints[Joint] = JointParent;
end;
end;

-- Return all found joints
return Joints;

end;

-- Types of joints to assume should be preserved
local ManualJointTypes = Support.FlipTable { 'Weld', 'ManualWeld', 'ManualGlue', 'Motor', 'Motor6D' };

function SearchJoints(Haystack, Part, Whitelist)
-- Searches for and returns manual joints in `Haystack` involving `Part` and other parts in `Whitelist`

local Joints = {};

-- Search the haystack for joints involving `Part`
for _, Item in pairs(GetChildren(Haystack)) do

-- Check if this item is a manual, intentional joint
if ManualJointTypes[Item.ClassName] and
(Whitelist[Item.Part0] and Whitelist[Item.Part1]) then

-- Save joint and state if intentional
Joints[Item] = Item.Parent;

end;

end;

-- Return the found joints
return Joints;

end;

function RestoreJoints(Joints)
-- Restores the joints from the given `Joints` data

-- Restore each joint
for Joint, JointParent in pairs(Joints) do
Joint.Parent = JointParent;
end;

end;

function PreserveJoints(Part, Whitelist)
-- Preserves and returns intentional joints of `Part` connecting parts in `Whitelist`

-- Get the part's joints
local Joints = GetPartJoints(Part, Whitelist);

-- Save the joints from being broken
for Joint in pairs(Joints) do
Joint.Parent = nil;
end;

-- Return the joints
return Joints;

end;

function CreatePart(PartType)
-- Creates and returns new part based on `PartType` with sensible defaults
Expand Down
3 changes: 2 additions & 1 deletion Tools/Move/FreeDragging.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local BoundingBox = require(Tool.Core.BoundingBox)
local Libraries = Tool:WaitForChild 'Libraries'
local Support = require(Libraries:WaitForChild 'SupportLibrary')
local MoveUtil = require(script.Parent:WaitForChild 'Util')
local JointUtils = require(Libraries:WaitForChild("JointUtils"))

-- Create class
local FreeDragging = {}
Expand Down Expand Up @@ -515,8 +516,8 @@ function FreeDragging:FinishDragging()

-- Restore the original state of each part
for Part, State in pairs(self.InitialPartStates) do
JointUtils.RestoreJoints(State.Joints)
Part:MakeJoints()
Core.RestoreJoints(State.Joints)
Part.CanCollide = State.CanCollide
Part.Anchored = State.Anchored
end
Expand Down
3 changes: 2 additions & 1 deletion Tools/Move/HandleDragging.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local BoundingBox = require(Tool.Core.BoundingBox)
-- Libraries
local Libraries = Tool:WaitForChild 'Libraries'
local MoveUtil = require(script.Parent:WaitForChild 'Util')
local JointUtils = require(Libraries:WaitForChild("JointUtils"))

-- Create class
local HandleDragging = {}
Expand Down Expand Up @@ -140,8 +141,8 @@ function HandleDragging:AttachHandles(Part, Autofocus)

-- Make joints, restore original anchor and collision states
for Part, State in pairs(self.InitialPartStates) do
JointUtils.RestoreJoints(State.Joints)
Part:MakeJoints()
Core.RestoreJoints(State.Joints)
Part.CanCollide = State.CanCollide
Part.Anchored = State.Anchored
end
Expand Down
Loading