Ooops
May 26, 2020, 06:57:33 PM

Author Topic: [bb] CalculateNormals by sswift [ 1+ years ago ]  (Read 1072 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] CalculateNormals by sswift [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : CalculateNormals
Author : sswift
Posted : 1+ years ago

Description : This function calculates both the face and vertex normals for a mesh using a method which does NOT smooth across vertcies that sit at the same location in space.  If two faces do not share a vertex, no smoothing will take place.  This allows you to more easily build levels which have sharp corners.  For exmaple, if you make a cube which has six seperate sides, with no vertcies shared between sides, this function will smooth it properly, whereas the built in function will not.

Code :
Code: BlitzBasic
  1. Dim Face_NX#(32768)
  2. Dim Face_NY#(32768)
  3. Dim Face_NZ#(32768)
  4.                
  5. Dim Vertex_ConnectedTris(32768)
  6. Dim Vertex_TriList(32768, 32)
  7.  
  8.  
  9. ; -------------------------------------------------------------------------------------------------------------------
  10. ; This function calculates and sets the normals for a mesh.
  11. ;
  12. ; Should probably update this so that it can recursively loop through all of an entities children as well.
  13. ; -------------------------------------------------------------------------------------------------------------------
  14. Function Calculate_Normals(ThisMesh)
  15.        
  16.         ; Loop through all surfaces of the mesh.
  17.         Surfaces = CountSurfaces(ThisMesh)
  18.         For LOOP_Surface = 1 To Surfaces
  19.  
  20.                 Surface_Handle = GetSurface(ThisMesh, LOOP_Surface)
  21.  
  22.                 ; Reset the number of connected polygons for each vertex.
  23.                 For LoopV = 0 To 32767 
  24.                         Vertex_ConnectedTris(LoopV) = 0
  25.                 Next   
  26.        
  27.                 ; Loop through all triangles in this surface of the mesh.
  28.                 Tris = CountTriangles(Surface_Handle)
  29.                 For LOOP_Tris = 0 To Tris-1
  30.  
  31.                         ; Get the vertices that make up this triangle.
  32.                                 Vertex_0 = TriangleVertex(Surface_Handle, LOOP_Tris, 0)
  33.                                 Vertex_1 = TriangleVertex(Surface_Handle, LOOP_Tris, 1)
  34.                                 Vertex_2 = TriangleVertex(Surface_Handle, LOOP_Tris, 2)
  35.        
  36.                         ; Adjust the number of triangles each vertex is connected to and
  37.                         ; store this triangle in each vertex's list of triangles it is connected to.
  38.                                 ConnectedTris = Vertex_ConnectedTris(Vertex_0)
  39.                                 Vertex_TriList(Vertex_0, ConnectedTris) = LOOP_Tris
  40.                                 Vertex_ConnectedTris(Vertex_0) = ConnectedTris + 1
  41.  
  42.                                 ConnectedTris = Vertex_ConnectedTris(Vertex_1)
  43.                                 Vertex_TriList(Vertex_1, ConnectedTris) = LOOP_Tris
  44.                                 Vertex_ConnectedTris(Vertex_1) = ConnectedTris + 1
  45.  
  46.                                 ConnectedTris = Vertex_ConnectedTris(Vertex_2)
  47.                                 Vertex_TriList(Vertex_2, ConnectedTris) = LOOP_Tris
  48.                                 Vertex_ConnectedTris(Vertex_2) = ConnectedTris + 1
  49.  
  50.                         ; Calculate the normal for this face.
  51.  
  52.                                 ; Get the corners of this face:
  53.                                 Ax# = VertexX#(Surface_Handle, Vertex_0)
  54.                                 Ay# = VertexY#(Surface_Handle, Vertex_0)
  55.                                 Az# = VertexZ#(Surface_Handle, Vertex_0)
  56.  
  57.                                 Bx# = VertexX#(Surface_Handle, Vertex_1)
  58.                                 By# = VertexY#(Surface_Handle, Vertex_1)
  59.                                 Bz# = VertexZ#(Surface_Handle, Vertex_1)
  60.  
  61.                                 Cx# = VertexX#(Surface_Handle, Vertex_2)
  62.                                 Cy# = VertexY#(Surface_Handle, Vertex_2)
  63.                                 Cz# = VertexZ#(Surface_Handle, Vertex_2)
  64.  
  65.                                 ; Triangle 1
  66.                                 ; Get the vectors for two edges of the triangle.
  67.                                 Px# = Ax#-Bx#
  68.                                 Py# = Ay#-By#
  69.                                 Pz# = Az#-Bz#
  70.  
  71.                                 Qx# = Bx#-Cx#
  72.                                 Qy# = By#-Cy#
  73.                                 Qz# = Bz#-Cz#
  74.  
  75.                                 ; Compute their cross product.
  76.                                 Nx# = Py#*Qz# - Pz#*Qy#
  77.                                 Ny# = Pz#*Qx# - Px#*Qz#
  78.                                 Nz# = Px#*Qy# - Py#*Qx#
  79.  
  80.                                 ; Store the face normal.
  81.                                 Face_NX#(LOOP_Tris) = Nx#
  82.                                 Face_NY#(LOOP_Tris) = Ny#
  83.                                 Face_NZ#(LOOP_Tris) = Nz#
  84.  
  85.                 Next
  86.  
  87.                 ; Now that all the face normals for this surface have been calculated, calculate the vertex normals.
  88.                 Vertices = CountVertices(Surface_Handle)
  89.                 For LOOP_Vertices = 0 To Vertices-1
  90.  
  91.                         ; Reset this normal.
  92.                         Nx# = 0
  93.                         Ny# = 0
  94.                         Nz# = 0
  95.  
  96.                         ; Add the normals of all polygons which are connected to this vertex.
  97.                         Polys = Vertex_ConnectedTris(LOOP_Vertices)
  98.                                
  99.                         For LOOP_Polys = 0 To Polys-1
  100.  
  101.                                 ThisPoly = Vertex_TriList(LOOP_Vertices, LOOP_Polys)
  102.  
  103.                                 Nx# = Nx# + Face_NX#(ThisPoly)
  104.                                 Ny# = Ny# + Face_NY#(ThisPoly)
  105.                                 Nz# = Nz# + Face_NZ#(ThisPoly)                 
  106.                                
  107.                         Next   
  108.                                
  109.                         ; Normalize the new vertex normal.
  110.                         ; (Normalizing is scaling the vertex normal down so that it's length = 1)
  111.  
  112.                                 Nl# = Sqr(Nx#^2 + Ny#^2 + Nz#^2)
  113.  
  114.                                 ; Avoid a divide by zero error if by some freak accident, the vectors add up to 0.
  115.                                 ; If Nl# = 0 Then Nl# = 0.1
  116.  
  117.                                 Nx# = Nx# / Nl#
  118.                                 Ny# = Ny# / Nl#
  119.                                 Nz# = Nz# / Nl#
  120.  
  121.                         ; Set the vertex normal.
  122.                        
  123.                                 VertexNormal Surface_Handle, LOOP_Vertices, Nx#, Ny#, Nz#
  124.                                 ;VertexColor Surface_Handle, LOOP_Vertices, polys*127, polys*127, polys*127
  125.                
  126.                 Next
  127.  
  128.         Next
  129.  
  130. End Function


Comments :


Wings(Posted 1+ years ago)

 Swift... this code saved my terrain  :D(build in normals in b3d has some buggs then using several alpha surface)


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal