Need help with applying physics to Models, Parts when using Gerstner waves

Hello!

So i have a script that creates realistic waves using gerstner waves but what I want to do now and what I can’t really figure out how to do is making it so when a player or a part or a model is in the ocean it moves realistically along with the waves.

Here’s the script that creates the waves:

-- Define the parameters of the waves
local n = 4 -- number of waves
local A = {0.1, 0.05, 0.03, 0.02} -- amplitude of each wave
local k = {2.0, 3.0, 1.5, 2.5} -- wavenumber of each wave
local theta = {0.3, 0.5, 0.8, 1.0} -- direction of each wave
local omega = {} -- angular frequency of each wave
local phi = {} -- phase of each wave

-- Calculate the angular frequency and phase of each wave
for i = 1, n do
	print("1")
	omega[i] = math.sqrt(9.81 * k[i])
	phi[i] = math.random() * 2 * math.pi
end

-- Function to calculate the height of the water surface at a given point (x, y, t) and deform the mesh
function calculateWaveHeightAndDeformMesh(x, y, t)
	print("2")
	for _, bone in ipairs(workspace.FBXImportGeneric.Plane:GetDescendants()) do
		
		local pos = bone.WorldCFrame.Position
	
		local h = 0
		
		for i = 1, n do
			
			h = h + A[i] * math.cos(k[i] * (pos.X * math.cos(theta[i]) + pos.Z * math.sin(theta[i])) - omega[i] * t + phi[i])
			
		end
		local offset = Vector3.new(0, h, 0)
		
		bone.Transform = bone.Transform * CFrame.new(offset)

		
	end
end

-- Call the function once outside of the loop to initialize the mesh deformation
calculateWaveHeightAndDeformMesh(0, 0, 0)

-- Apply the deformation to all bones in the mesh at every frame
while true do
	calculateWaveHeightAndDeformMesh(0, 0, tick())

	wait()
end

1 Like

I have booked some progress cause the part now moves realistically with the sea(still need some changes before it really really is realistic) but as soon as i add more parts to the workspace the mesh just deforms like real weird. And i think that that is because the module script i used is being called multiple times so i changed the script in the part but now all the parts dissapear and the mesh isn’t being deformed

Here’s the module script:

local module = {}

-- Define the parameters of the waves
local n = 2 -- number of waves
local A = {0.05, 0.02, 0.0075, 0.005} -- amplitude of each wave
local k = {1.0, 1.5, 1.5, 2.5} -- wavenumber of each wave
local theta = {0.3, 0.5, 0.8, 1.0} -- direction of each wave
local omega = {} -- angular frequency of each wave
local phi = {} -- phase of each wave

-- Calculate the angular frequency and phase of each wave
for i = 1, n do
	omega[i] = math.sqrt(9.81 * k[i])
	phi[i] = math.random() * 2 * math.pi
end

-- Function to calculate the normal vector of the water surface at a given point (x, z, t)
function module.calculateWaveNormal(x, z, t)
	local dx = 0
	local dz = 0
	for i = 1, n do
		local angle = k[i] * (x * math.cos(theta[i]) + z * math.sin(theta[i])) - omega[i] * t + phi[i]
		dx = dx - k[i] * A[i] * math.sin(angle) * math.cos(theta[i])
		dz = dz - k[i] * A[i] * math.sin(angle) * math.sin(theta[i])
	end
	local normal = Vector3.new(-dx, 1, -dz).Unit
	return normal
end

-- Function to calculate the tangent vector of the water surface at a given point (x, z, t)
function module.calculateWaveTangent(x, z, t)
	local dx = 0
	local dz = 0
	for i = 1, n do
		local angle = k[i] * (x * math.cos(theta[i]) + z * math.sin(theta[i])) - omega[i] * t + phi[i]
		dx = dx - k[i] * A[i] * math.sin(angle) * math.cos(theta[i])
		dz = dz - k[i] * A[i] * math.sin(angle) * math.sin(theta[i])
	end
	local tangent = Vector3.new(1, dx, dz).Unit
	return tangent
end

-- Function to calculate the height of the water surface at a given point (x, z, t) and deform the mesh
function module.calculateWaveHeightAndDeformMesh(x, z, t)
	local h = 0
	for _, bone in ipairs(workspace.FBXImportGeneric.Plane:GetDescendants()) do
		local pos = bone.WorldCFrame.Position
		for i = 1, n do
			h = h + A[i] * math.cos(k[i] * (pos.X * math.cos(theta[i]) + pos.Z * math.sin(theta[i])) - omega[i] * t + phi[i])
		end
		local offset = Vector3.new(0, h, 0)
		bone.CFrame = bone.CFrame + offset
	end
	local normal = module.calculateWaveNormal(x, z, t) -- calculate the normal vector of the water surface at the given point
	local tangent = module.calculateWaveTangent(x, z, t) -- calculate the tangent vector of the water surface at the given point
	return h, normal, tangent -- return both the height and normal and tangent vectors of the water surface at the given point
end
-- Return the module table so that its contents can be accessed from another script
return module

And here’s the normal script inside each part that i want to move realistically with the sea:

-- Get a reference to the Debris object
local debris = game:GetService("Debris")

-- Get a reference to all the parts
local parts = {script.Parent} -- add all the parts to this table

-- Get a reference to the Gerstner wave generation module script
local GerstnerWaveModuleScript = game.StarterPlayer.StarterPlayerScripts:WaitForChild("ModuleScript")
local GerstnerWaveModule = require(GerstnerWaveModuleScript)

-- Function to update the CFrame of all the parts
local function updateParts()
	-- Call the calculateWaveHeightAndDeformMesh function once per frame
	local pos = parts[1].Position
	local h, normal, tangent = GerstnerWaveModule.calculateWaveHeightAndDeformMesh(pos.X, pos.Z, tick())
	local offset = Vector3.new(0, h * 0.5, 0)

	-- Update the CFrame of all the parts
	for _, part in ipairs(parts) do
		part.CFrame = CFrame.new(part.Position + offset) * CFrame.fromMatrix(Vector3.new(), tangent, normal) -- align both the RightVector and UpVector of each part's CFrame with the calculated tangent and normal vectors respectively
	end

	-- Schedule the next execution of this function
	debris:AddItem(parts[1], 0) -- pass the first part in the parts table as the first argument to the AddItem method
end

-- Schedule the first execution of the updateParts function
debris:AddItem(parts[1], 0) -- pass the first part in the parts table as the first argument to the AddItem method

If anyonre has an idea how to fix this issue please reply!