I’m using the GerstnerWave module for an oceans project I’m making right now. I’m using EditableMeshes to achieve the wave effect. Basically, I’m struggling with re-syncing waves after deleting one and then readding it (essential for an LOD system)
As you can see, it seems to be resetting the clock on the wave despite the fact that I’m passing tick() as an argument to GerstnerWave. This makes me think it’s a change that needs to be made to the module, but I’m not smart enough to understand that module fully yet.
Do you have any suggestions for how I could resync the wave? Here’s the GerstnerWave module:
local GerstnerWave = {
WaveInfo = {},
System = {}
}
type WaveInfo = { any }
local tableInsert = table.insert
local twoPi = 2 * math.pi
local sqrt = math.sqrt
local cos = math.cos
local sin = math.sin
local atan2 = math.atan2
local vector3New = Vector3.new
local vector3Zero = Vector3.zero
local vector3XAxis = Vector3.xAxis
local vector3ZAxis = Vector3.zAxis
local vector2New = Vector2.new
function GerstnerWave.WaveInfo.new( direction: Vector2, waveLength: number, steepness: number, gravity: number ): WaveInfo
return {
direction or vector3New(1, 0),
waveLength or 100,
steepness or 0.3,
gravity or 9.8
}
end
function GerstnerWave:GetTransform( waves: { WaveInfo }, position: Vector2, runTime: number )
local transform = vector3Zero
for _, wave: WaveInfo in next, waves do
transform += GerstnerWave.System:CalculateTransform(position, runTime, false, GerstnerWave.System:CalculateWave(unpack(wave)))
end
return transform
end
function GerstnerWave:GetHeightAndNormal( waves: { WaveInfo }, position: Vector2, runTime: number )
local transform = vector3Zero
local tangent = vector3XAxis
local binormal = vector3ZAxis
for _, wave: WaveInfo in next, waves do
local resultTransform, resultTangent, resultBiNormal = GerstnerWave.System:CalculateTransform(position, runTime, true, GerstnerWave.System:CalculateWave(unpack(wave)))
transform += resultTransform
tangent += resultTangent
binormal += resultBiNormal
end
return transform, tangent, binormal
end
function GerstnerWave:GetRotationAngle(transform1: Vector3, transform2: Vector3, rotationFactor: number)
return atan2((transform1 - transform2).Y, rotationFactor)
end
function GerstnerWave.System:CalculateWave(...)
local _, waveLength, steepness, gravity = ...
local waveNumber = twoPi/waveLength
local waveSpeed = sqrt(gravity/waveNumber)
local waveAmplitude = steepness/waveNumber
return waveNumber, waveSpeed, waveAmplitude, ...
end
function GerstnerWave.System:CalculateTransform(
position: Vector2,
runTime: number,
calculateNormals: boolean,
waveNumber: number,
waveSpeed: number,
waveAmplitude: number,
waveDirection: Vector2,
_,
steepness: number
)
local wavePhase = waveNumber * (waveDirection:Dot(vector2New(position.X, position.Y)) - waveSpeed * runTime)
local cosf = cos(wavePhase)
local sinf = sin(wavePhase)
local tangent, binormal
if calculateNormals then
local steepSinF = (steepness * sinf)
local directionX = waveDirection.X
local directionY = waveDirection.Y
tangent = vector3New(-directionX * directionX * steepSinF, directionX * (steepness * cosf), -directionX * directionY * steepSinF)
binormal = vector3New(-directionY * directionY * steepSinF, directionY * (steepness * cosf), -directionY * directionY * steepSinF)
end
return vector3New(waveDirection.X * (waveAmplitude * cosf), waveAmplitude * sinf, waveDirection.Y * (waveAmplitude * cosf)), tangent, binormal
end
return GerstnerWave
Here’s the section of my code that sets the wave: (Let me know if you need to see more. I can DM you the full code.)
for _, VertexID in Vertices do
local Position = EditableMesh:GetPosition(VertexID)
local WorldPosition = Object.CFrame:PointToWorldSpace(Position * Object.Size / Object.MeshSize)
local GeneratePosition = Vector2.new(WorldPosition.X, WorldPosition.Z)
EditableMesh:SetPosition(VertexID, Position + (GerstnerWaves:GetTransform(Waves, GeneratePosition, tick()) * Vector3.new(0,1,0)))
end
Thanks guys!!