forked from Pakz001/Monkey2-3D
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExample - Random Terrain with Water.monkey2
246 lines (180 loc) · 5.14 KB
/
Example - Random Terrain with Water.monkey2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"
Using std..
Using mojo..
Using mojo3d..
Global mapsize:Int=512
Class MyWindow Extends Window
Field _scene:Scene
Field _fog:FogEffect
Field _camera:Camera
Field _light:Light
Field _material:Material
Field _terrain:Terrain
Field _water:Model
Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
Super.New( title,width,height,flags )
startgame()
End Method
Method OnRender( canvas:Canvas ) Override
RequestRender()
Fly( _camera,Self )
_scene.Render( canvas,_camera )
If Keyboard.KeyReleased(Key.Space) Then startgame()
canvas.DrawText( "Width="+Width+", Height="+Height+", FPS="+App.FPS,0,0 )
canvas.DrawText("Cursor up/down/left/right a/z and Left mouse button - space = new map.",0,20)
End Method
Method startgame()
If _terrain Then _terrain.Destroy()
If _camera Then _camera.Destroy()
If _light Then _light.Destroy()
If _material Then _material.Discard()
If _scene Then
_scene.Terrains.Clear()
End If
_scene = Scene.GetCurrent()
_fog=New FogEffect( Color.Black,480,512 )
'create camera
'
_camera=New Camera
_camera.Near=1
_camera.Far=512
_camera.Move( 0,66,0 )
'create light
'
_light=New Light
_light.RotateX( Pi/2 ) 'aim directional light 'down' - Pi/2=90 degrees.
Local waterMaterial:=New WaterMaterial
waterMaterial.ScaleTextureMatrix( 10,10 )
waterMaterial.ColorTexture=Texture.ColorTexture( Color.SeaGreen )
waterMaterial.Roughness=0
waterMaterial.Velocities=New Vec2f[](
New Vec2f( .01,.03 ),
New Vec2f( .02,.05 ) )
_water=Model.CreateBox( New Boxf( -mapsize,1,-mapsize,mapsize,5,mapsize ),1,1,1,waterMaterial )
_material = New PbrMaterial( New Color(.5,.05,0),1,0.5 )
_material.ScaleTextureMatrix( 32,32 )
Local heightMap:= New Pixmap(mapsize,mapsize)
heightMap = makeheightmap()
_terrain=New Terrain( heightMap,New Boxf( -mapsize,0,-mapsize,mapsize,64,mapsize ),_material )
heightMap.Discard()
End Method
End
'
' This function creates a pixmap with a random map
' inside it for the use of the mojo3d terrain.
'
'
Function makeheightmap:Pixmap()
SeedRnd(Millisecs()) 'Different seed is different map
Local pm:Pixmap
pm = New Pixmap(mapsize,mapsize)
pm.Clear(Color.Black)
' This is a lambda function that increases the
' color on the pixmap by a bit.
Local myrect:=Lambda(x1:int,y1:Int,w:Int,h:Int)
Local inc:Float=Rnd(-0.1,0.1)
For Local y2:=y1 Until y1+h
For Local x2:=x1 Until x1+w
If x2>=0 And x2<mapsize And y2>=0 And y2<mapsize
Local mc:Color
mc = pm.GetPixel(x2,y2)
Local r:Float=mc.r + inc
Local g:Float=mc.g + inc
Local b:Float=mc.b + inc
If r>1 Then r=1
If g>1 Then g=1
If b>1 Then b=1
If r<0 Then r=0
If g<0 Then g=0
If b<0 Then b=0
pm.SetPixel(x2,y2,New Color(r,g,b))
End If
Next
Next
End Lambda
' This lambda takes one input coordinate where
' it takes a color and next and below it also a color
' this then is avaraged(divided by 3) and put back
' on the pixmap(blurring/smoothing it)
'
Local blur:=Lambda(x1:Int,y1:Int)
Local c1:Color = pm.GetPixel(x1,y1)
Local c2:Color = pm.GetPixel(x1+1,y1)
Local c3:Color = pm.GetPixel(x1,y1+1)
Local nr:Float=(c1.r+c2.r+c3.r)/3
pm.SetPixel(x1,y1,New Color(nr,nr,nr))
End Lambda
' Here we create a map
For Local i:=0 Until (mapsize*mapsize)/200
Local x:Int=Rnd(-50,mapsize)
Local y:Int=Rnd(-50,mapsize)
Local w:Int=Rnd(5,mapsize/4)
Local h:Int=Rnd(5,mapsize/4)
myrect(x,y,w,h)
Next
'blur some
For Local i:=0 Until (mapsize*mapsize)*3
blur(Rnd(1,mapsize-1),Rnd(1,mapsize-1))
Next
For Local y:Int = 4 Until mapsize-5
For Local x:Int = 4 Until mapsize-5
If pm.GetPixel(x,y).r < .25 And pm.GetPixel(x,y).r >.15
Local h:Float=.16
pm.SetPixel(x,y,New Color(h,h,h))
End If
Next
Next
For Local y:Int = 0 Until mapsize-2
For Local x:Int = 0 Until mapsize-2
If pm.GetPixel(x,y).r < .5 And pm.GetPixel(x,y).r > .30
Local h:Float=.31
pm.SetPixel(x,y,New Color(h,h,h))
End If
Next
Next
'
'blur some
For Local i:=0 Until (mapsize*mapsize)*3
blur(Rnd(1,mapsize-1),Rnd(1,mapsize-1))
Next
Return pm
End Function
' Taken from the mojo3d test
Function Fly( entity:Entity,view:View )
If Keyboard.KeyDown( Key.Up )
entity.RotateX( .1 )
Else If Keyboard.KeyDown( Key.Down )
entity.RotateX( -.1 )
Endif
If Keyboard.KeyDown( Key.Q )
entity.RotateZ( .1 )
Else If Keyboard.KeyDown( Key.W )
entity.RotateZ( -.1 )
Endif
If Keyboard.KeyDown( Key.Left )
entity.RotateY( .1,True )
Else If Keyboard.KeyDown( Key.Right )
entity.RotateY( -.1,True )
Endif
If Mouse.ButtonDown( MouseButton.Left )
If Mouse.X<view.Width/3
entity.RotateY( .1,True )
Else If Mouse.X>view.Width/3*2
entity.RotateY( -.1,True )
Else
entity.Move( New Vec3f( 0,0,.1 ) )
Endif
Endif
If Keyboard.KeyDown( Key.A )
entity.MoveZ( .5 ) '( New Vec3f( 0,0,.1 ) )
Else If Keyboard.KeyDown( Key.Z )
entity.MoveZ( -.5 ) '( New Vec3f( 0,0,-.1 ) )
Endif
End Function
Function Main()
New AppInstance
New MyWindow
App.Run()
End