Help crater function

Blitz3D Forums/Blitz3D Programming/Help crater function

Guy Fawkes(Posted 2008) [#1]
Can someone please show an example of how to use this crater function thing?

Function crater(entity,terrain,radius#=1,th#=100,hardness#=1)
			ex#=EntityX(entity)
			ez#=EntityZ(entity)

			For x=-radius To radius
			For z=-radius To radius
				If Sqr(x^2+z^2)<=radius And hardness<>0
					d#=Sqr(x*x+z*z)
					
					h#=TerrainHeight(terrain,ex+x,ez+z)
										
					scale#=th/hardness
					
					h=h+d/scale-radius/scale
					If h<0 Then h=0
					ModifyTerrain terrain,ex+x,ez+z,h,True
				EndIf
			Next
			Next
End Function


Thanks! =)

~DarkShadowWing~


Ross C(Posted 2008) [#2]
It seems to produce a dent in the terrain. All the square root stuff will be to produce a deep hiol at the centre, and smooth out towards the edges.


Guy Fawkes(Posted 2008) [#3]
i know. but i cant seem to get it to work.. =/

~DarkShadowWing~


_PJ_(Posted 2008) [#4]
Well, what's not working with it?

How big is your terain?

What parameters are you using in the function?

If you could post a little of your code, it might help us see where it's not working :)


Guy Fawkes(Posted 2008) [#5]
For my code, you need to use particle candy.

Text 10,10,"USE FULLSCREEN (Y/N)?"

While a% = 0
	a% = GetKey()
	If a = 122 Or a = 121
		Graphics3D 800,600,0
	Else If a = 110
		Graphics3D 800,600,0,2
	Else
		a = 0
	End If
Wend

SetBuffer backBuffer()

Include "..\particle candy.bb"

; --------------------------------------------------
; VARIABLES
; --------------------------------------------------

; FOR DELTA TIME CALCULATION
Const  TARGET_FPS# = 60.0	
Global previous%   = MilliSecs()	
Global lastFPS%    = MilliSecs()
Global frames%
Global delta#

Global b

; MOUSE LOOK
Global mouseXAxis# = -1.0
Global mouseYAxis# = 1.0
Global mouseXSpd#  = 0.0
Global mouseYSpd#  = 0.0

MoveMouse 400,300 : HidePointer

; --------------------------------------------------
; CREATE 3D OBJECTS
; --------------------------------------------------
Global TerrainTex = LoadTexture("..\Media\terraintex.jpg")
Global SkyTex     = LoadTexture("..\Media\sky.jpg")
Global CometTex   = LoadTexture("..\Media\fountain.jpg")

Global Terrain = LoadTerrain("..\Media\terrain.bmp")
ScaleEntity    Terrain,1,10,1
PositionEntity Terrain, -128,-10,-128
ScaleTexture   TerrainTex,256,256
EntityTexture  Terrain,TerrainTex
EntityFX       Terrain,1
EntityColor    Terrain,200,200,200

Global Sky   = LoadMesh("..\Media\sky.b3d")
positionentity Sky,0,-150,0
scaleentity    Sky,5,3,5
entitytexture  Sky,SkyTex
EntityFX       Sky,1

Const NUMCOMETS% = 4
Dim Comets%(NUMCOMETS)
Dim Xspeeds#(NUMCOMETS)
Dim Yspeeds#(NUMCOMETS)
Dim Zspeeds#(NUMCOMETS)

For i% = 1 To NUMCOMETS
	Xspeeds(i) = Rnd(-.5,.5)
	Yspeeds(i) = Rnd(-2,-1)
	Zspeeds(i) = Rnd(-.5,.5)
	Comets (i) = LoadMesh("..\Media\comet.b3d")
	EntityTexture  Comets(i),CometTex
	PositionEntity Comets(i),Rnd(-5,5),150,Rnd(-5,5)
	ScaleEntity    Comets(i),.02,.02,.02
Next

Global Player = CreatePivot()
PositionEntity  Player,0,2,0

Global CameraXRotate = CreatePivot(Player)

Global Cam   = CreateCamera(CameraXRotate)
CameraFogMode  Cam,1
CameraFogRange Cam,1,235
CameraFogColor Cam,170,170,200

Global Light = CreateLight()
PositionEntity Light,0,100,0

CreateListener(Cam, .005, 1, 100)

Global terrain_modified

; --------------------------------------------------
; CREATE EMITTERS & PARTICLES
; --------------------------------------------------
SetParticleWind 1.0
InitParticles(Cam,"..\Media\particles.png", 3)

; COMET TRAIL SMOKE
P1 = CreateParticleType()
ParticleType_SetImage    		  P1,9
ParticleType_SetSpeed    		  P1,0,0
ParticleType_SetRandomSpeed	  P1,.02,0,.02
ParticleType_SetSize     		  P1,2,1,4,7
ParticleType_SetAlpha    		  P1,.5,.2,-.25
ParticleType_SetWeight   		  P1,0,0
ParticleType_SetRotation 		  P1,1,0
ParticleType_SetColor    		  P1,40,40,50,60,0,0,0
ParticleType_SetEmissionAngle P1,3,360
ParticleType_SetStartOffsets  P1,0,0,0,0,0,0
ParticleType_SetLifeTime 		  P1,4000
ParticleType_SetBounce        P1,0.1,0,0
ParticleType_SetAddedBlend    P1,0

; COMET TRAIL FIRE
P2 = CreateParticleType()
ParticleType_SetImage    		  P2,9
ParticleType_SetSpeed    		  P2,0,0
ParticleType_SetRandomSpeed	  P2,.02,0,.02
ParticleType_SetSize     		  P2,2.5,1,4,6
ParticleType_SetAlpha    		  P2,1,.2,-3
ParticleType_SetWeight   		  P2,-.5,0
ParticleType_SetRotation 		  P2,1,0
ParticleType_SetColor    		  P2,250,150,0,40,-100,-100,0
ParticleType_SetEmissionAngle P2,3,180
ParticleType_SetStartOffsets  P2,0,0,-10,5,0,0
ParticleType_SetLifeTime 		  P2,1000
ParticleType_SetBounce        P2,0.1,0,0
ParticleType_SetAddedBlend    P2,1

; IMPACT SNOW
P3 = CreateParticleType()
ParticleType_SetImage    		  P3,9
ParticleType_SetSpeed    		  P3,35,10
ParticleType_SetSize     		  P3,3,3,6,5
ParticleType_SetAlpha    		  P3,1,.2,-1.5
ParticleType_SetWeight   		  P3,5,3
ParticleType_SetRotation 		  P3,1,0
ParticleType_SetColor    		  P3,200,200,240,90,0,0,0
ParticleType_SetEmissionAngle P3,3,130
ParticleType_SetInnerAngle    P3,45
ParticleType_SetStartOffsets  P3,0,0,0,0,0,0
ParticleType_SetLifeTime 		  P3,2000
ParticleType_SetBounce        P3,0,0,0
ParticleType_SetAddedBlend    P3,0

; IMPACT STONES
P4 = CreateParticleType()
ParticleType_SetImage    		  P4,8
ParticleType_SetSpeed    		  P4,75,20
ParticleType_SetSize     		  P4,.5,.5
ParticleType_SetAlpha    		  P4,1,0,0
ParticleType_SetWeight   		  P4,10,8
ParticleType_SetRotation 		  P4,1,500
ParticleType_SetColor    		  P4,200,200,240,90,0,0,0
ParticleType_SetEmissionAngle P4,3,90
ParticleType_SetInnerAngle    P4,25
ParticleType_SetStartOffsets  P4,0,0,0,0,0,0
ParticleType_SetLifeTime 		  P4,2000
ParticleType_SetBounce        P4,-.5,.7,3
ParticleType_SetAddedBlend    P4,0

; CREATE AND FEED EMITTERS
Dim TrailEmitters%  (NUMCOMETS)
Dim ImpactEmitters% (NUMCOMETS)

For i% = 1 To NUMCOMETS
	TrailEmitters(i)      = CreateEmitter (Comets(i))
	PositionEntity          TrailEmitters(i),EntityX(Comets(i)),EntityY(Comets(i)),EntityZ(Comets(i))
	Emitter_SetSound        TrailEmitters(i),"..\Media\cometfly.mp3",0
	Emitter_AddParticleType TrailEmitters(i), P1, 0,360000,85
	Emitter_AddParticleType TrailEmitters(i), P2, 0,360000,100
	Emitter_Start           TrailEmitters(i)

	ImpactEmitters(i)     = CreateEmitter ()
	Emitter_SetSound        ImpactEmitters(i),"..\Media\explosion.mp3",0
	Emitter_AddParticleType ImpactEmitters(i), P3, 0,500,150
	Emitter_AddParticleType ImpactEmitters(i), P4, 0,200,150
Next

; --------------------------------------------------
; MAIN LOOP
; --------------------------------------------------
While Not KeyHit(1)
	; GET FPS & DELTA TIME
	now%   = MilliSecs()
	delta  = (now - previous) / (1000 / TARGET_FPS)
	If delta <= 0 Then delta = 0.001
	previous = now
	frames   = frames + 1
	If now - lastFPS >= 1000
		currFPS% = frames : frames = 0 : lastFPS = now
	End If

	MouseLook
	b=UpdateComets()		
	UpdateParticles
	
	RenderWorld
	
	Text 5,0, "FPS: " + currFPS + " PARTICLES TOTAL: " + pt_numParticles + " PARTICLES RENDERED: " + pt_particlesRendered
	Text 5,40,"USE MOUSE TO LOOK AROUND"
	Text 5,80,b
	Text 5,100,terrain_modified
	Flip 0
Wend

FreeParticleSystem : End

; ==============================================
; FUNCTION: Crater
; ==============================================
Function crater(entity,terrain,radius#=1,th#=100,hardness#=1)
			ex#=EntityX(entity)
			ez#=EntityZ(entity)

			For x=-radius To radius
			For z=-radius To radius
				If Sqr(x^2+z^2)<=radius And hardness<>0
					d#=Sqr(x*x+z*z)
					
					h#=TerrainHeight(terrain,ex+x,ez+z)
										
					scale#=th/hardness
					
					h=h+d/scale-radius/scale
					If h<0 Then h=0
					ModifyTerrain(terrain,ex+x,ez+z,h,True) : terrain_modified = 1
				EndIf
			Next
			Next
End Function

; ----------------------------------------------
; FUNCTION: MOVE COMETS
; ----------------------------------------------
Function UpdateComets()
For i% = 1 To NUMCOMETS
	; MOVE COMET
	MoveEntity Comets(i),Xspeeds(i)*delta, Yspeeds(i)*delta, Zspeeds(i)*delta
	; HIT GROUND?
	If EntityY(Comets(i)) < -5 Then
		PositionEntity ImpactEmitters(i),EntityX(Comets(i)),EntityY(Comets(i))+1,EntityZ(Comets(i))
		Emitter_Start  ImpactEmitters(i)
		Emitter_Start  TrailEmitters(i)
		PositionEntity Comets(i),Rnd(-100,100),150,Rnd(-100,100)
		shakeradius = 1
			height# = TerrainHeight(terrain,TerrainX(terrain, EntityX(cam), EntityY(cam), EntityZ(cam)),TerrainZ(terrain, EntityX(cam), EntityY(cam), EntityZ(cam)))
			b=crater(ImpactEmitters(i),terrain,radius#=1,th#=height#,hardness#=1)
					
	End If
				
Next

Return b

End Function


Global angle#
Global shakeradius#
; ----------------------------------------------
; FUNCTION: MOUSE LOOK
; ----------------------------------------------
Function MouseLook()
	; MOUSE LOOK
  mouseXSpd# = MouseXSpeed()
  mouseYSpd# = MouseYSpeed()
  MoveMouse 400,300
	pitch# = mouseYSpd * mouseYAxis * .25
	yaw#   = mouseXSpd * mouseXAxis * .25
	angle  = angle + pitch
	
	If angle > 90 angle = 90 ElseIf angle < -80 angle = -80
	
 	If angle < 90 And angle > -80 TurnEntity CameraXRotate,pitch#,0,0
	TurnEntity Player,0,yaw#,0
	
	; SHAKE CAMERA
	PositionEntity Cam,Rnd(-shakeradius,shakeradius),Rnd(-shakeradius,shakeradius),Rnd(-shakeradius,shakeradius)

	; SLOW OUT SHAKING
	If shakeradius > 0
		shakeradius = shakeradius - .05 * delta
	Else
		shakeradius = 0
	End If
		
End Function


Thanks! =)

~DarkShadowWing~


_PJ_(Posted 2008) [#6]
I dont have Particle Candy,but I dont think it';s relevant.
What does stand out just looking at your code, however, is the line:

			b=crater(ImpactEmitters(i),terrain,radius#=1,th#=height#,hardness#=1)


and then
Return b

Followed later by
Text 5,80,b


I'm gonna make a wild guess that your value for b only shows 0 and that's why you're thinking it wont work?

The Crater Function is a 'void' not a 'return' function. It simply 'Does its thing' and then goes back to wherever it was called from. There's no value being passed to 'b' so it defaults to NULL.

-----------------------
Provided the "ImpactEmitters(i)" is correctly identified, and the terrain is not placed so it may be lower than -5 or too high above -5, then I think it is indeed working fine.

There's other things, mostly aesthetic or efficient, such as it may be better to use Types for the Comets rather than an array, and changing between "Terrain" and "terrain"


Guy Fawkes(Posted 2008) [#7]
is there any way you could make an example that doesnt require particle candy? =) that way i would understand most if not all of it =)

~DarkShadowWing~


_PJ_(Posted 2008) [#8]
Graphics3D 800,600,32,2
	Global Terrain=LoadTerrain("Terrain.bmp")
	ScaleEntity Terrain,0.5,10,0.5
	Global Texture=CreateTexture(128,128)
	SetBuffer TextureBuffer(Texture)
		ClsColor 0,0,64
		Cls
		Color 255,255,255
		Rect 1,1,126,126
	SetBuffer BackBuffer()
	EntityTexture Terrain,Texture
	FreeTexture Texture
	Global Camera=CreateCamera()
	MoveEntity Camera,0,12,0
	RotateEntity camera,5,-45,0
	Global light=CreateLight()
	Global Comet=CreateSphere(50)
	Global Direction=Rand(360)
	RotateEntity Comet,0,Direction,0
	PositionEntity Comet,Rand(16,32),40,Rand(16,32)
	Spd#=-0.1
	While Not KeyDown(1)
		Spd#=Spd#-0.1
		MoveEntity Comet,0,0,0.5
		TranslateEntity Comet,0,Spd#,0
		If EntityY#(Comet)<=-12
			crater(Comet,Terrain)
				Direction=Rand(360)
				RotateEntity Comet,0,Direction,0
				PositionEntity Comet,Rand(16,32),40,Rand(16,32)
				Spd#=-0.1
		EndIf
	UpdateWorld
	RenderWorld
	Flip
	Wend
	FreeEntity Light
	FreeEntity Terrain
	FreeEntity Comet
	FreeEntity Camera
	ClearWorld
	EndGraphics
	End
	
; ==============================================
; FUNCTION: Crater
;(( Note - Fixed a few # ))
; ==============================================
Function crater(entity,Terrain,radius#=5,th#=10,hardness#=0.5)
	ex#=EntityX#(entity)
	ez#=EntityZ#(entity)
	For x#=-radius# To radius#
		For z#=-radius To radius#
			If Sqr(x#^2+z#^2)<=radius# And hardness#<>0
				d#=Sqr(x#*x#+z#*z#)	
				h#=TerrainHeight#(Terrain,ex+x#,ez+z#)
				scale#=th#/hardness#
				h#=h#+d#/scale#-radius#/scale#
				If h#<0 Then h#=0
				ModifyTerrain(Terrain,ex+x#,ez+z#,h#,True) 
			EndIf
		Next
	Next
End Function



H. T. U.(Posted 2008) [#9]
LOL, I put a crater function in the code archives 2 days ago and people are already having trouble with it and making improvements! Although the number fixes shouldn't be necessary unless you have an oddly disproportionate terrain and have to add the step command(once a variable is defined as a floating point, Blitz keeps it that way). As I mentioned in the archives, the function assumes the terrain to have a resolution of one coordinate per Blitz unit, and the Step command may be needed if this isn't true in your program.


_PJ_(Posted 2008) [#10]
I didn't actually go over the function in detail, just adjusted the parameters to fit where I'd quickly improvised a terrain.

The crater function does work. All I did was add # to the floats for 'completeness' just in case :)

I didnt check the notes to whatever in the Code Archives for it, here, looking specifically at DarkShadowWings' issue.

Though I like it, it's a nifty function!


Guy Fawkes(Posted 2008) [#11]
Indeed

~DarkShadowWing~


Guy Fawkes(Posted 2008) [#12]
Thanks for the help Malice. =) Now I get it =)

~DarkShadowWing~