Sadly, it will not work on a sphere. It would appear that the script is trying to keep the faces of the mesh facing upward and will try to do the same to the sphere’s faces. Also it won’t receive the collisions for some reason…waves_sphere_edit.blend (940 KB)
The dampening should be possible through editing some of the calls to BPY but i’m not entirely sure which ones
Thanks for the feedback.
After uploading I realised how unreadable the code was.
I’ve cleaned it up and have been working on speeding things up. It’s not there yet but things are improving.
Yes this can be done to a sphere and the waves can be dampened too.
My Pleasure.
Here’s a faster version that interlaces the updates (if you get my drift). This gives me as many as 7000 faces at 60fps on my modestly endowed computer.
Disappointingly, it doesn’t want to work in the standalone player. Still it’s been fun testdriving the little boats.
Hi Blue Print.
It already spreads the updating over 6 frames, alternating between updating positions and normals. I gave up trying to spread it out further as the flicker gets too obvious (at least on my computer).
As far as your suggestion goes, I wouldn’t know how to implement it. This is my first go at Blender and Python.
if it helps, the script works by checking the relative displacement between neighbouring vertices and applies equal and opposite forces based on that displacement. I wouldn’t know how to go about telling it to check only displaced verts without checking to see which ones were displaced. or something… Still, it might be fun trying.
very cool, i optimized the first code , adding the normals … check if is enought fast 8)
( without (very poors) tricks with the frequency 8) )
own = bge.logic.getCurrentController().owner
if "run" not in own.attrDict:
import random
import mathutils
R = random.random
speed = 1. #Set wave speed
height = 100.0 #Set Wave Force
verts = {}
mesh = own.meshes[0]
verts_in_poly = []
for polyID in range(0, mesh.numPolygons):
p = mesh.getPolygon(polyID)
a1 = mesh.getVertex(0,p.v1)
a2 = mesh.getVertex(0,p.v2)
a3 = mesh.getVertex(0,p.v3)
verts_in_poly.append([a1,a2,a3])
mathutils_geometry_normal = mathutils.geometry.normal
def run_verts_in_poly():
for verts in verts_in_poly:
poly_n = mathutils_geometry_normal(*[v.XYZ for v in verts])
for v in verts:
v.setNormal(poly_n)
for vert in [mesh.getVertex(0, vn) for vn in range(mesh.getVertexArrayLength(0))]:
c = tuple(vert.XYZ)
if c not in verts:
frame = random.uniform(1,3)
verts[c] = [[], frame, c[2]]
verts[c][0].append(vert)
waves = [verts[k] for k in verts]
waves[0][1] = 1.0001
def calc_h(frame):
if frame <= 2.0: # If frame is less than half of animation
h = (frame **2.0 - 3.0*frame) + 2.0 # Formula for parabolic coordinate plotting by frame num
else:
frame = frame -1.0 # Reset frame by half its animation
h = -((frame **2.0 - 3.0*frame) + 2.0) # INVERTED Formula for parabolic coordinate plotting by frame num
h = h * height/100
return h
def run():
if not "control" in own:
own["control"] = [waves[0][1],]
own["frames"] = []
own["index"] = 0
if len(own["control"])>=2:
if own["index"]+1 >= len(own["frames"]):
own["index"] = 0
else:
own["index"]+=1
for vs in own["frames"][own["index"]]:
fp,fn,p,n=vs
fp(p)
fn(n)
return
print(waves[0][1])
if len(own["control"])==1:
if waves[0][1] < own["control"][0]:
own["control"].append(waves[0][1])
elif len(own["control"])==2:
if waves[0][1] > own["control"][0]:
own["control"].append(waves[0][1])
return
for wave in waves:
wave[1] += speed/height
if wave[1] >= 3.0:
wave[1] = 1.0
frame = wave[1]
h = calc_h(frame)
for vert in wave[0]:
vert.z = wave[2] + h
run_verts_in_poly()
frameverts = []
for wave in waves:
for vert in wave[0]:
frameverts.append([vert.setXYZ,vert.setNormal,vert.getXYZ(),vert.getNormal()])
own["frames"].append(frameverts)
own["run"] = run
own["run"]()
Not really, I just made a quick example with some grass planes. To give best results though you must rotate the grass sideways, give it apply rotation and then rotate it back to normal - that way the grass moves sideways, pretty good looking and realistic.