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

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

Offline 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