Ooops
January 26, 2021, 06:09:09 AM

### Author Topic: [bb] Instant Cliffs by Mr Snidesmin [ 1+ years ago ]  (Read 676 times)

#### BlitzBot

• Jr. Member
• Posts: 1
##### [bb] Instant Cliffs by Mr Snidesmin [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Instant Cliffs
Author : Mr Snidesmin
Posted : 1+ years ago

Description : This function applies textures to a mesh's triangles based on the gradient of the triangles slope.

This way you can easily apply a cliff texture to cliffs etc without having to do it manually.

Up to 5 'grades' of texture can be applied with the function as it is, but it can be modified for more or less with ease.

Example is included. You just need to create the textures and terrain mesh.  An easier way to create a terrain that you might want to use is here: <a href="codearcs001a.html?code=1081" target="_blank">http://blitzbasic.com/codearcs/codearcs.php?code=1081[/url]

Code :
Code: BlitzBasic
1. Function GradePaintTerrainMesh%(m%, g1#, g2#, g3#, g4#, bGrad0%, bGrad1%, bGrad2%, bGrad3%, bGrad4%)
2.         m2% = CreateMesh()
3.
4.         s_g0% = CreateSurface(m2)
5.         s_g1% = CreateSurface(m2)
6.         s_g2% = CreateSurface(m2)
7.         s_g3% = CreateSurface(m2)
8.         s_g4% = CreateSurface(m2)
9.
10.         For i% = 1 To CountSurfaces(m)
11.                 s% = GetSurface(m, i)
12.                 For it% = 0 To CountTriangles(s)-1
13.                         v0% = TriangleVertex(s, it, 0)
14.                         v1% = TriangleVertex(s, it, 1)
15.                         v2% = TriangleVertex(s, it, 2)
16.
17.                         v0x# = VertexX(s, v0)
18.                         v0y# = VertexY(s, v0)
19.                         v0z# = VertexZ(s, v0)
20.                         v0u# = VertexU(s, v0)
21.                         v0v# = VertexV(s, v0)
22.                         v0w# = VertexW(s, v0)
23.                         v0nx# = VertexNX(s, v0)
24.                         v0ny# = VertexNY(s, v0)
25.                         v0nz# = VertexNZ(s, v0)
26.                         v0red# = VertexRed(s, v0)
27.                         v0green# = VertexRed(s, v0)
28.                         v0blue# = VertexRed(s, v0)
29.                         v0alpha# = VertexAlpha(s, v0)
30.
31.                         v1x# = VertexX(s, v1)
32.                         v1y# = VertexY(s, v1)
33.                         v1z# = VertexZ(s, v1)
34.                         v1u# = VertexU(s, v1)
35.                         v1v# = VertexV(s, v1)
36.                         v1w# = VertexW(s, v1)
37.                         v1nx# = VertexNX(s, v1)
38.                         v1ny# = VertexNY(s, v1)
39.                         v1nz# = VertexNZ(s, v1)
40.                         v1red# = VertexRed(s, v1)
41.                         v1green# = VertexRed(s, v1)
42.                         v1blue# = VertexRed(s, v1)
43.                         v1alpha# = VertexAlpha(s, v1)
44.
45.                         v2x# = VertexX(s, v2)
46.                         v2y# = VertexY(s, v2)
47.                         v2z# = VertexZ(s, v2)
48.                         v2u# = VertexU(s, v2)
49.                         v2v# = VertexV(s, v2)
50.                         v2w# = VertexW(s, v2)
51.                         v2nx# = VertexNX(s, v2)
52.                         v2ny# = VertexNY(s, v2)
53.                         v2nz# = VertexNZ(s, v2)
54.                         v2red# = VertexRed(s, v2)
55.                         v2green# = VertexRed(s, v2)
56.                         v2blue# = VertexRed(s, v2)
57.                         v2alpha# = VertexAlpha(s, v2)
58.
59.
60.                         grad# = TriGradient(s, it)
61.                         If grad < g1 Then
62.                                 s2 = s_g0
63.                         ElseIf grad < g2 Then
64.                                 s2 = s_g1
65.                         ElseIf grad < g3 Then
66.                                 s2 = s_g2
67.                         ElseIf grad < g4 Then
68.                                 s2 = s_g3
69.                         Else
70.                                 s2 = s_g4
71.                         End If
72.
73.                         v0% = AddVertex(s2, v0x, v0y, v0z, v0u, v0v, v0w)
74.                         v1% = AddVertex(s2, v1x, v1y, v1z, v1u, v1v, v1w)
75.                         v2% = AddVertex(s2, v2x, v2y, v2z, v2u, v2v, v2w)
76.                         VertexNormal s2, v0, v0nx, v0ny, v0nz
77.                         VertexNormal s2, v1, v1nx, v1ny, v1nz
78.                         VertexNormal s2, v2, v2nx, v2ny, v2nz
79.                         VertexColor s2, v0, v0red, v0green, v0blue, v0alpha
80.                         VertexColor s2, v1, v1red, v1green, v1blue, v1alpha
81.                         VertexColor s2, v2, v2red, v2green, v2blue, v2alpha
82.                         AddTriangle s2, v0, v1, v2
83.                 Next
84.         Next
85.
86.         PaintSurface s_g0, bGrad0
87.         PaintSurface s_g1, bGrad1
88.         PaintSurface s_g2, bGrad2
89.         PaintSurface s_g3, bGrad3
90.         PaintSurface s_g4, bGrad4
91.
92.         FreeEntity m
93.         Return m2
94. End Function
95.
96.
97. Function TriGradient#(surface%, triangle%)
98.         Local v0%,v1%,v2%
99.         Local v0x#, v0y#, v0z#
100.         Local v1x#, v1y#, v1z#
101.         Local v2x#, v2y#, v2z#
102.         Local tx#, ty#, tz#
103.         Local m1#, m2#, c1#, c2#
104.         Local ax#, ay#, az#
105.         Local theta#, argument#, modulus#
106.         Local i%
107.
108.         ;Special case 1: Is the whole triangle parallel to xz-plane?
109.         v0x = VertexX(surface, TriangleVertex(surface, triangle, 0))
110.         v0y = VertexY(surface, TriangleVertex(surface, triangle, 0))
111.         v0z = VertexZ(surface, TriangleVertex(surface, triangle, 0))
112.         v1x = VertexX(surface, TriangleVertex(surface, triangle, 1))
113.         v1y = VertexY(surface, TriangleVertex(surface, triangle, 1))
114.         v1z = VertexZ(surface, TriangleVertex(surface, triangle, 1))
115.         v2x = VertexX(surface, TriangleVertex(surface, triangle, 2))
116.         v2y = VertexY(surface, TriangleVertex(surface, triangle, 2))
117.         v2z = VertexZ(surface, TriangleVertex(surface, triangle, 2))
118.         If v0y = v1y And v1y = v2y Then
119.                 ;Yes, so gradient is 0
120.                 Return 0
121.         End If
122.
123.         ;Step 1:
124.         ;Sort out vertices in order of height (y-axis), v0=bottom, v1=middle, v2=top
125.         For i=0 To 2
126.         v% = TriangleVertex(surface, triangle, i)
127.                 If v0=0 Then v0 = v
128.                 If v2=0 Then v2 = v
129.
130.                 If VertexY(surface,v) > VertexY(surface,v2) Then v2 = v
131.                 If VertexY(surface,v) < VertexY(surface,v0) Then v0 = v
132.     Next
133.         For i=0 To 2
134.         v% = TriangleVertex(surface, triangle, i)
135.                 If v0<>v And v2<>v Then v1 = v
136.     Next
137.         v0x = VertexX(surface, v0)
138.         v0y = VertexY(surface, v0)
139.         v0z = VertexZ(surface, v0)
140.         v1x = VertexX(surface, v1)
141.         v1y = VertexY(surface, v1)
142.         v1z = VertexZ(surface, v1)
143.         v2x = VertexX(surface, v2)
144.         v2y = VertexY(surface, v2)
145.         v2z = VertexZ(surface, v2)
146.
147.         ;Step 2: Translate lowest point To 0,0,0
148.         tx = v0x
149.         ty = v0y
150.         tz = v0z
151.         v0x = v0x - tx
152.         v0y = v0y - ty
153.         v0z = v0z - tz
154.         v1x = v1x - tx
155.         v1y = v1y - ty
156.         v1z = v1z - tz
157.         v2x = v2x - tx
158.         v2y = v2y - ty
159.         v2z = v2z - tz
160.
161.         ;Special case 2: Is the line (v1,v2) is parallel to xz-plane?
162.         If v1y = v2y Then
163.                 ;Yes, so invert the triangle in the y-axis
164.                 v0y = v1y
165.                 v1y = 0
166.                 v2y = 0
167.                 ;Lowest point is now v2, highest is v0, so swap them:
168.                 tx# = v2x
169.                 ty# = v2y
170.                 tz# = v2z
171.                 v2x = v0x
172.                 v2y = v0y
173.                 v2z = v0z
174.                 v0x = tx
175.                 v0y = ty
176.                 v0z = tz
177.                 ;Re-do translation:
178.                 v0x = v0x - tx
179.                 v0y = v0y - ty
180.                 v0z = v0z - tz
181.                 v1x = v1x - tx
182.                 v1y = v1y - ty
183.                 v1z = v1z - tz
184.                 v2x = v2x - tx
185.                 v2y = v2y - ty
186.                 v2z = v2z - tz
187.         End If
188.
189.
190.         ;Step 3: Find Point a, such that y(a) = 0 and y is on the line (v2, v1)
191.         ;Line Equations:
192.         ;y=m1x+c1
193.         ;y=m2z+c2
194.         m1 = (v2y-v1y) / (v2x-v1x)
195.         m2 = (v2y-v1y) / (v2z-v1z)
196.         c1 = v1y - m1 * v1x
197.         c2 = v1y - m1 * v1z
198.         ay = 0
199.         ax = -c1/m1
200.         az = -c2/m2
201.
202.         ;Special case 3: is v1 at y=0
203.         If v1y = 0 Then
204.                 ;Yes, therefore a = v1
205.                 ax = v1x
206.                 ay = v1y
207.                 az = v1z
208.         End If
209.
210.         ;Step 4. Rotate all points v0,v1,v2, a about y-axis so that point a is at x=0
211.         theta# = -ATan2(az, ax) ;Angle to rotate
212.         ;NOTE: Actually only v2's z-component will be used, so let's be lazy and only calculate v2z.
213.         ;;Rotate v0
214.         ;argument# = ATan2(v0z, v0x)
215.         ;modulus# = Sqr(v0x^2 + v0z^2)
216.         ;v0x = modulus * Cos(theta+argument)
217.         ;v0z = modulus * Sin(theta+argument)
218.         ;;Rotate v1
219.         ;argument# = ATan2(v1z, v1x)
220.         ;modulus# = Sqr(v1x^2 + v1z^2)
221.         ;v1x = modulus * Cos(theta+argument)
222.         ;v1z = modulus * Sin(theta+argument)
223.         ;;Rotate v2
224.         argument# = ATan2(v2z, v2x)
225.         modulus# = Sqr(v2x^2 + v2z^2)
226.         ;v2x = modulus * Cos(theta+argument)
227.         v2z = modulus * Sin(theta+argument)
228.         ;;Rotate a
229.         ;argument# = ATan2(az, ax)
230.         ;modulus# = Sqr(ax^2 + az^2)
231.         ;ax = modulus * Cos(theta+argument)
232.         ;az = modulus * Sin(theta+argument)
233.
234.
235.         ;Step 5. Calculate the gradient, and return the value.
236.         Return Abs(v2y / v2z)
237. End Function
238.
239.
240. ;Example:
241. Graphics3D 800, 600, 0, 2
242.
243. b0 =  LoadBrush("grass_flat.bmp",1+8)
244. b1 =  LoadBrush("grass_slope.bmp",1+8)
245. b2 =  LoadBrush("grass+rocks.bmp",1+8)
246. b3 =  LoadBrush("rocks.bmp",1+8)
247. b4 =  LoadBrush("cliff.bmp",1+8)
248.
249. terrain = LoadMesh("terrain.3ds")
250. terrain = GradePaintTerrainMesh(terrain, 0.1, 0.3, 0.8, 1.2, b0, b1, b2, b3, b4)
251.
252. cam = CreateCamera()
253.
254. PositionEntity cam, 100, 100, 100
255. PointEntity cam, terrain
256.
257. AmbientLight 200, 200, 200
258.
259. MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
260. FlushMouse
261.
262. While Not KeyHit(1)
263.         SetBuffer BackBuffer()
264.         UpdateWorld
265.         RenderWorld
266.         VWait
267.         Flip
268.
269.         dY# = EntityPitch(Cam)+MouseYSpeed()/2*0.5
270.         If dY > 89 Then dY = 89
271.         If dY < -89 Then dY = -89
272.         RotateEntity Cam, dY, EntityYaw(Cam)-(MouseXSpeed()/2)*0.5, 0
273.         MoveEntity Cam, 0, 0, (MouseDown(1)-MouseDown(2))*3
274.         MoveMouse GraphicsWidth()/2, GraphicsHeight()/2
275. Wend
276. End

Comments :

Ziltch(Posted 1+ years ago)

Great job.Now I will have to make some texture to suit!

aab(Posted 1+ years ago)

Very effective

SimplePortal 2.3.6 © 2008-2014, SimplePortal