oh yeah, thanks ill go and try it right away.
you may want to add that to the documentation aswell.
oh yeah, thanks ill go and try it right away.
you may want to add that to the documentation aswell.
How did you get the bones to be all parented to the plane?
Blender isnât totally my thing, so Iâm not sure if I would be of much help.
Check out this tutorial here and if you still have the problem, try asking it there.
Question, very late
Have you gotten around to make this work completely or not? I´m looking for a solution to bone collission within oceans/seas which are animated
That will be very difficult to do, as Roblox has not added support for collision detection with skinned meshes.
Collision detection isnât necessarily needed, it can be calculated without it
Theres multiple videos on it just look up âgerstner waves robloxâ
Take the object youâd want as a sort of âboyant/boyancy blockâ
Great tutorial imo, thanks a ton!
I did some research thru APIs and the ¨Skinned MeshParts are live!¨ post and came across this API:
¨ TransformedWorldCFrame¨
Describes the combined CFrame
offset of the bone and the current animation offset in world space.
This could help with collision, possibly
Another way I´ve seen before is create triangles on the gerstner waves, which follow the same wave path to detect collision way easier (but more performance impact probably)
Along with that I came across this example:
This is probably the closest we can get to collision detection for skinned meshes, for now.
Thatâs some good research right there. However, unless there is an official implementation, I donât plan on updating the module with collisions. I donât believe it will exactly be performant in real situations, but itâs always worth a shot!
Is it possible to detect if a player/camera is inside the water?
@iamtryingtofindname
Is there any way to condense your expansive and useful module into a single function that takes a vector 3 and returns where that vector 3 should be at that returned time?
-- call a function and pass the origin point before the translation (and perhaps the settings?)
Wave.GerstnerPoint(Vector3)
-- expected return is the vector3 post-translation
x, y, z
This has to be possible and simple (but math and coding arenât my areas of expertise)
^ Any arbitrary bone can be translated by the gerstner function you have, as long as it exists in the workspace, therefore any arbitrary point should have its own translation. This is obvious, I think.
I tried a couple methods and all failed, however, the method that made the most headway was:
Putting all necessary functions in a serverscript for the individual floating part
Taking the partâs position as the vector3 to be translated
Placing the translated vector3 as the bodypositionâs position
The one problem I faced was that I could not correctly isolate and carry over your perlin noise function.
Yeah sure I can add that real quick
Lemme know if it works. Download the updated module:
Source:
-- Added per request of @Desired_Knowledge
function Wave:GerstnerPoint(point: Vector3)
local WorldPos = point
local Settings = self._settings
local Direction = Settings.Direction
if Direction == EmptyVector2 then
-- Use Perlin Noise
Direction = Vector2.new(math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,1),math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,0))
else
Direction = GetDirection(Settings,WorldPos)
end
local transform = newCFrame(Gerstner(WorldPos,Settings.WaveLength,Direction,Settings.Steepness,Settings.Gravity,self._time))
return transform, point+transform
end
Just realized I never hit reply lol
It works properly, but its not synced with the waves. It doesnât seem to be the same wave at all.
Now, I did make edits to the module to have the plane anchor to the HumanoidRootPart and keep the points where they should be, had the plane never moved. I move the plane, and subtract the humanoidrootpartâs x/z position from the worldposition of the bones. In this way, the water is basically infinite. There must be some issue in the way I did that though.
Iâm trying to have an infinite ocean that uses only 1 plane and also has waves that are pretty synced from client to server to clients. I asked about the point method so I could add swimming and floating physics, as well as a check for if your camera is under water.
If thatâs an edit you can walk me through, or make altogether (as long as it isnât asking too much), that would be extremely appreciated and helpful. I can commission you, otherwise.
The problem with Gerstner waves is that there is no mathematically correct way to get the waveheight at a given xz-position.
The best you can do is use approximations. What I found by researching the problem is that you can achieve a pretty good result by plugging the wave formula in twice. As in you first calculate one offset of the position, then pass that new position in the formula again to extract the height.
How would I do that using these above methods?
Something like this:
function getHeight(XZPos)
local w = computeDisplacement(XZPos)
local correctedXZPos = Vector2.new(XZPos.X + w.X, XZPos.Y + w.Z)
return computeDisplacement(correctedXZPos).Y
end
computeDisplacement()
is a function that takes in an XZ-coordinate and returns the offset on that point (Vector3).
I got some version of it working, but my issue now is that the points used are the objectâs origin points. That means I canât have the items move around the x/z plane outside of the gerstnerâs movement. If I allow them to move, then they arenât in sync with the wave plane anymore. Thatâs the issue with swimming, camera underwater check, and boat floating.
This seems like a weird issue.
The Gerstner formula should work for any point up to infinity. Are you referencing the bones somehow? Could you show the relevant code pieces?
Well, I wasnât entirely clear in my explanation. The objects float with a gerstner wave pattern and it roughly matches the waves (this could be an issue with my client server synchrony method).
These objects are stationary and are not dynamic. Think of them like buoys that just bob around their origin like bones would.
My problem arises when I have dynamic objects (that donât really follow the x/z aspect of the gerstner). Say, for instance:
As for the code sample, I actually deleted what I had for the floating objects. It was practically the gerstner function for the bones with some changes so it would put the return in a bodyposition.
Gerstner formula function
function GerstnerWave(SamplePosition,Wavelength,Direction,Steepness,Gravity,SampleTick)
local k = (2 * math.pi) / Wavelength
local a = Steepness/k
local d = Direction.Unit
local c = math.sqrt(Gravity / k)
local f = k * d:Dot(Vector2.new(SamplePosition.X,SamplePosition.Z)) - c * SampleTick
local cosF = math.cos(f)
--Displacement Vectors
local dX = (d.X * (a * cosF))
local dY = a * math.sin(f)
local dZ = ( d.Y * (a * cosF))
return Vector3.new(dX,dY,dZ)
end
point transform (takes a vector3 argument)
function gerstnertransform(v)
local WorldPos = v
local Wave1 = GerstnerWave(WorldPos,100,Vector2.new(.5,0),.14,3,SyncModule:Time()*timemodifier*1)
local Wave2 = GerstnerWave(WorldPos,120,Vector2.new(.8,.2),.07,15,SyncModule:Time()*timemodifier*0.6)
local Wave3 = GerstnerWave(WorldPos,300,Vector2.new(.7,1),.04,15,SyncModule:Time()*timemodifier*0.3)
local TotalDisplacement = Wave1+Wave2+Wave3
return TotalDisplacement
end