ripple effect

Blitz3D Forums/Blitz3D Programming/ripple effect

Ross C(Posted 2003) [#1]
Hey, i was wonder how to go about doing a rippling effect. For example, how do you know which vertexs to choose when your rippling. Is there a way to say, choose the nearest vertex to this point, or what? How would you'z go about doing it?


Neo Genesis10(Posted 2003) [#2]
I'd be interested to know if there's a shortcut for this too. I've been mapping each vertex beforehand which is real pain and means I have to do it everytime I use the effect.


Stevie G(Posted 2003) [#3]
Just knocked this up. It's a bit rough but may be of use?

Graphics3D 640,480

light=CreateLight()
camera=CreateCamera()
Global size=20
Global scale=8
Global grid = make_grid()

PositionEntity camera,0,100,-50
PointEntity camera,grid
ripple# = 0

While Not KeyDown(1)

ripple = (ripple + 5 ) Mod 360

s=GetSurface(grid,1)
For v=0 To CountVertices(s)-1
d#=Sqr(VertexX(s,v)*VertexX(s,v)+VertexZ(s,v)*VertexZ(s,v))
a#=(-d*10)+ripple
VertexCoords s,v,VertexX(s,v),scale*Sin(a),VertexZ(s,v)
Next

UpdateNormals grid

RenderWorld()
Flip


Wend

;============================================================================================
;GRID =======================================================================================
;============================================================================================

Function make_grid()

mesh=CreateMesh():s=CreateSurface(mesh)

For x=0 To size
For z=0 To size
v0=AddVertex(s,(x-size*.5)*scale,0,(z-size*.5)*scale)
c#=100+50*( ( x+z ) Mod 2 )
VertexColor s,v0,0,c*.5,c
Next
Next

For x=0 To size-1
For z=0 To size-1
v0=x+z*(size+1)
v1=v0+1
v2=v1+(size+1)
v3=v0+(size+1)
AddTriangle s,v0,v1,v2
AddTriangle s,v2,v3,v0
Next
Next

EntityFX mesh,2

Return mesh

End Function


Ross C(Posted 2003) [#4]
:D !!! Very nice function!! Suppose it can't just import a mesh and use this. Is there a way to find the vertexs at a given point?


Bot Builder(Posted 2003) [#5]
actually, that function should work for anything. the vertexx(),vertexy(),and vertez() give coords


Ross C(Posted 2003) [#6]
interesting piece of code :) I'll need to study it some more. Thnak you !


Todd(Posted 2003) [#7]
Here's something I threw together real quick. It's a function for doing ripples. You give it mesh, frequency, wave size (height), phase, center point, and the normal of the wave, and it takes care of the rest of it for you. Look at the example to see how exactly it works. To make the wave actually "wave" you just increment the phase, 0 to 360. That doesn't work in the example, but it should get you started.

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

Camera=CreateCamera()
PositionEntity Camera,0,2,-5

Light=CreateLight(2)
AmbientLight 60,60,60
LightRange Light,8
LightColor Light,255,200,150
PositionEntity Light,2,4,0

Mesh=CreateQuad(40)
EntityColor Mesh,0,60,180
EntityPickMode Mesh,2
EntityShininess Mesh,0.2

Type Point
	Field x#,y#,z#
End Type

Pt.Point=Null

While Not KeyDown(1)
Cls

	Count#=Count#+90

	PointEntity Camera,Mesh
	If Pt.Point=Null
		If CameraPick(Camera,MouseX(),MouseY())
			If MouseDown(1)
				Pt.Point=New Point	;Wave Center
				Pt\x#=PickedX()
				Pt\y#=PickedY()
				Pt\z#=PickedZ()
				Nm.Point=New Point	;Wave Normal
				Nm\y#=1
				Ripple(Mesh,200,0.2,Count#,Pt,Nm)
				UpdateNormals Mesh				
			EndIf
		EndIf
	EndIf

UpdateWorld
RenderWorld

	If OldTime < MilliSecs()
		OldTime=MilliSecs()+1000
		Fps=FrameCount
		FrameCount=0
	Else
		FrameCount=FrameCount+1
	EndIf
	
	Text 16,16,Fps+" FPS"

Flip
Wend

Function Ripple(Mesh,Freq#,Height#,Phase#,Ct.Point,Nm.Point)
	For Sf=1 To CountSurfaces(Mesh)
		Surf=GetSurface(Mesh,Sf)
		For Vert=0 To CountVertices(Surf)-1
			Vx#=VertexX(Surf,Vert)
			Vy#=VertexY(Surf,Vert)
			Vz#=VertexZ(Surf,Vert)
			TFormPoint Vx#,Vy#,Vz#,Mesh,0
			Vx#=TFormedX()
			Vy#=TFormedY()
			Vz#=TFormedZ()
			Dx#=Ct\x#-Vx#
			Dy#=Ct\y#-Vy#
			Dz#=Ct\z#-Vz#
			Dd#=Sqr((Dx#*Dx#)+(Dy#*Dy#)+(Dz#*Dz#))
			Vx#=Vx#+(Sin(-Phase#+(Dd#*Freq#))*Height#)*Nm\x#
			Vy#=Vy#+(Cos(-Phase#+(Dd#*Freq#))*Height#)*Nm\y#
			Vz#=Vz#+(Sin(-Phase#+(Dd#*Freq#))*Height#)*Nm\z#
			TFormPoint Vx#,Vy#,Vz#,0,Mesh
			Vx#=TFormedX()
			Vy#=TFormedY()
			Vz#=TFormedZ()
			VertexCoords(Surf,Vert,Vx#,Vy#,Vz#)
		Next
	Next
End Function

Function CreateQuad(msDt#,msParent=0)
	Mesh=CreateMesh(msParent)
	Surf=CreateSurface(Mesh)
	For x#=0 To msDt#
	For y#=0 To msDt#
		x2#=x#-(msDt#/2)
		y2#=y#-(msDt#/2)
		v0=AddVertex(Surf,x2#/msDt#,0,y2#/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v1=AddVertex(Surf,(x2#+1)/msDt#,0,y2#/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v2=AddVertex(Surf,x2#/msDt#,0,(y2#+1)/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v3=AddVertex(Surf,(x2#+1)/msDt#,0,(y2#+1)/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		AddTriangle(Surf,v2,v1,v0)
		AddTriangle(Surf,v2,v3,v1)
	Next
	Next
	ScaleMesh Mesh,4,4,4
	UpdateNormals Mesh
	Return Mesh
End Function



Ross C(Posted 2003) [#8]
Hey Todd, thanks :)

I got this for my wave to repeat, but it seems wrong somehow.

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

Camera=CreateCamera()
PositionEntity Camera,0,2,-5

Light=CreateLight(2)
AmbientLight 60,60,60
LightRange Light,8
LightColor Light,255,200,150
PositionEntity Light,2,4,0

Mesh=CreateQuad(40)
EntityColor Mesh,0,60,180
EntityPickMode Mesh,2
EntityShininess Mesh,0.2

Type Point
	Field x#,y#,z#
End Type

Pt.Point=Null

Global Count#
Global loop;= 90

While Not KeyDown(1)
Cls

	Count#=Count#+1

	PointEntity Camera,Mesh
	If Pt.Point=Null
		If CameraPick(Camera,MouseX(),MouseY())
			If MouseDown(1)
				Pt.Point=New Point	;Wave Center
				Pt\x#=PickedX()
				Pt\y#=PickedY()
				Pt\z#=PickedZ()
				Nm.Point=New Point	;Wave Normal
				Nm\y#=1
				Ripple(Mesh,200,0.2,Count#,Pt,Nm)
				UpdateNormals Mesh
				ct=1				
			EndIf
		EndIf
	EndIf
	
	If ct=1 Then
		loop=loop+1:If loop>359 Then loop=0;ct=0
		FreeEntity Mesh
		Mesh=CreateQuad(20)
		EntityColor Mesh,0,60,180
		EntityPickMode Mesh,2
		EntityShininess Mesh,0.2
		ripple(Mesh,200,Sin(loop),Count*4,Pt,Nm)
		UpdateNormals Mesh
	End If
	
UpdateWorld
RenderWorld

	If OldTime < MilliSecs()
		OldTime=MilliSecs()+1000
		Fps=FrameCount
		FrameCount=0
	Else
		FrameCount=FrameCount+1
	EndIf
	
	Text 16,16,Fps+" FPS"
	If ct=1 Then Text 0,0,"pt\x="+pt\x+" py="+pt\y+" pz="+pt\z
Delay 1
Flip
Wend

Function Ripple(Mesh,Freq#,Height#,Phase#,Ct.Point,Nm.Point)
	For Sf=1 To CountSurfaces(Mesh)
		Surf=GetSurface(Mesh,Sf)
		For Vert=0 To CountVertices(Surf)-1
			Vx#=VertexX(Surf,Vert)
			Vy#=VertexY(Surf,Vert)
			Vz#=VertexZ(Surf,Vert)
			TFormPoint Vx#,Vy#,Vz#,Mesh,0
			Vx#=TFormedX()
			Vy#=TFormedY()
			Vz#=TFormedZ()
			Dx#=Ct\x#-Vx#
			Dy#=Ct\y#-Vy#
			Dz#=Ct\z#-Vz#
			Dd#=Sqr((Dx#*Dx#)+(Dy#*Dy#)+(Dz#*Dz#))
			Vx#=Vx#+(Sin(-Phase#+(Dd#*Freq#))*Height#)*Nm\x#
			Vy#=Vy#+(Cos(-Phase#+(Dd#*Freq#))*Height#)*Nm\y#
			Vz#=Vz#+(Sin(-Phase#+(Dd#*Freq#))*Height#)*Nm\z#
			TFormPoint Vx#,Vy#,Vz#,0,Mesh
			Vx#=TFormedX()
			Vy#=TFormedY()
			Vz#=TFormedZ()
			VertexCoords(Surf,Vert,Vx#,Vy#,Vz#)
		Next
	Next
End Function

Function CreateQuad(msDt#,msParent=0)
	Mesh=CreateMesh(msParent)
	Surf=CreateSurface(Mesh)
	For x#=0 To msDt#
	For y#=0 To msDt#
		x2#=x#-(msDt#/2)
		y2#=y#-(msDt#/2)
		v0=AddVertex(Surf,x2#/msDt#,0,y2#/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v1=AddVertex(Surf,(x2#+1)/msDt#,0,y2#/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v2=AddVertex(Surf,x2#/msDt#,0,(y2#+1)/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		v3=AddVertex(Surf,(x2#+1)/msDt#,0,(y2#+1)/msDt#,(x#)/msDt#,(msDt#-y#)/msDt#)
		AddTriangle(Surf,v2,v1,v0)
		AddTriangle(Surf,v2,v3,v1)
	Next
	Next
	ScaleMesh Mesh,4,4,4
	UpdateNormals Mesh
	Return Mesh
End Function


But Stevies code was more of what i wanted. I'm looking for a ripple to start from the centre and work it's way out. Once the ripple has passed, every thing before it returns to normal. Think the matrix when the helicopter crashes into the building. Thank you both, i'll look more into it :D