Feedback on my 'gravity simulation'


local RunService = game:GetService('RunService')
local ContentProvider = game:GetService("ContentProvider")

local Knit = require(game:GetService('ReplicatedStorage').Packages.Knit)

local NumberOfParticles = 1

local ParticleDensity = 2
local G = 6.6743 * 10e-11
local c = 299792458.0

local width = 1

type Particle = {
	Velocity: Vector3,
	Position: Vector3,
	Number: number,
	Mass: Vector3,
	Object: Instance
}

-------------------------------------

local ParticleService = Knit.CreateService {
	Name = "ParticleService",
	Particles = table.create(NumberOfParticles),
	Client = {
	},
}

--------------------------------------

local function CreateGridVertices(size, divisions, Grid)
	local vertices = {}
	local step = size / divisions
	local halfSize = size / 2

	
	for xStep = 0, divisions do
		local x = -halfSize + xStep * step
		local y = Grid.Position.Y
		for zStep = 0, divisions do
			local z = -halfSize + zStep * step
			table.insert(vertices, Vector3.new(x,y,z))
		end
	end
	
	for i, v in pairs(vertices) do
		local attachment = Instance.new('Attachment')
		attachment.Parent = Grid
		attachment.WorldPosition = v
		attachment.Name = i
	end
	
	local attachments = Grid:GetChildren()
	
	print(#attachments, vertices)
	
	local count = 0
	
	for i = 1, #attachments do
		
		if (i) % (divisions + 1) == 0 and i ~= 1 then
			continue
		end
		
		local beam = Instance.new('Beam')
		beam.Attachment0 = attachments[i]
		beam.Attachment1 = attachments[i + 1]
		beam.Parent = Grid
		beam.Name = i
		beam.Width0 = width
		beam.Width1 = width
		beam.Texture = 'rbxassetid://136011733'
		beam.TextureMode = Enum.TextureMode.Stretch
		beam.Color = ColorSequence.new(Color3.fromRGB(255,255,255))
		beam.FaceCamera = true
		beam.Transparency = NumberSequence.new(0.5)
	end
	
	for i=1, divisions + 1 do
		for j = i, (divisions+1) * (i * divisions), divisions + 1 do
			local beam = Instance.new('Beam')
			beam.Attachment0 = attachments[j]
			beam.Attachment1 = attachments[j + divisions + 1]
			beam.Parent = Grid
			beam.Name = i..':'..j
			beam.Width0 = width
			beam.Width1 = width
			beam.Texture = 'rbxassetid://136011733'
			beam.TextureMode = Enum.TextureMode.Stretch
			beam.Color = ColorSequence.new(Color3.fromRGB(255,255,255))
			beam.FaceCamera = true
			beam.Transparency = NumberSequence.new(0.5)
		end
	end
	
	for i, child in ipairs(Grid:GetChildren()) do
		--ContentProvider:PreloadAsync(child)
	end
	
	return vertices
end

local function CheckParticleCollision(newPosition, radius, positionTable)
	for index, position in pairs(positionTable) do
		if (newPosition - position).Magnitude < radius then
			return true
		end
	end
	return false
end


---------------------------------------

function ParticleService:UpdateGridVertices(vertices, positionTable)
	for i = 1, #vertices do
		
		local totalDisplacement = Vector3.new(0,0,0)
		for j, p in pairs(self.Particles) do
			local toObject = p.Position - vertices[i]
			local distance = toObject.Magnitude
			local rs = (2 * G * p.Mass) / (c * c)
			
			local dz = 2 * math.sqrt(rs * (distance - rs))
			totalDisplacement += Vector3.new(0, dz * 50e11, 0)
		end
		vertices[i] = Vector3.new(vertices[i].X,totalDisplacement.Y,vertices[i].Z)
	end
	
	--print(vertices[1])
	
	for i, attachment in pairs(workspace.GRID:GetChildren()) do
		if attachment:IsA('Attachment') then
			attachment.WorldPosition = vertices[i]
			 --if attachment.Position.Y ~= -20 then print(attachment.Position.Y) end
		end
	end
	
	return vertices

end


function ParticleService:KnitStart()
	local ParticleObject = workspace:FindFirstChild('Particle')
	local Grid = workspace:FindFirstChild("GRID")
	
	local positionTable = {}
	
	local Particles = self.Particles
	for i = 1, NumberOfParticles do
		Particles[i] = {
			Velocity = Vector3.new(1,0,1) * math.random(10,30),
			Position = Vector3.new(0,0,0),
			Number = i,
			Mass = 0,
			Object = ParticleObject:Clone()
		} :: Particle
		
		--Random particle position where no other particle is
		local newPosition
		
		local function tableInsert()
			table.insert(positionTable,newPosition)
			return true
		end
		
		repeat
			local x = math.random(1, 500)
			local y = math.random(150, 150)
			local z = math.random(1, 500)
			newPosition = Vector3.new(x,y,z)
		until not (positionTable[newPosition] and CheckParticleCollision(newPosition, Particles[i].Object.Size.Magnitude, positionTable)) and tableInsert()
		Particles[i].Position = newPosition
		Particles[i].Velocity = Vector3.new(math.random(-50,50),0,math.random(-50,50))
		
		Particles[i].Mass = Particles[i].Object.Size.Magnitude * ParticleDensity
		
		Particles[i].Object.Parent = workspace
	end
	
	local Vertices
	
	task.spawn(function()
		Vertices = CreateGridVertices(2000, 25, Grid)
		task.synchronize()
	end)
	
	RunService.Heartbeat:Connect(function(deltaTime)
		task.spawn(function()
			self:UpdateGridVertices(Vertices, positionTable)
			
			for i = 1, #Particles do
				local p = Particles[i]
				p.Position += p.Velocity * deltaTime
				p.Object.Position = p.Position
			end
			
			task.synchronize()
		end)
	end)
	
	
	ParticleObject:Destroy()
	--print(Vertices)
end


return ParticleService
1 Like

Cool, I’m not a physics guy but I’d rate this an 8/10

3 Likes

Since space time fabric doesnt exist in roblox, you can make springs. The closer an object it the more spring will pull

1 Like