October 24, 2021, 04:17:56

Author Topic: [bb] CenterMesh by Zethrax [ 1+ years ago ]  (Read 945 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] CenterMesh by Zethrax [ 1+ years ago ]
« on: June 29, 2017, 00:28:38 »
Title : CenterMesh
Author : Zethrax
Posted : 1+ years ago

Description : This function can be used to center a mesh where the mesh data is off-center.

Off-center meshes cause problems with fustrum culling, entity transformations, etc.

The function also returns x, y, z values for the original position of the mesh data, so that the mesh entity can be repositioned where it was originally.

EDIT: Edited to return the total vertex count, so that it may be used to check for an empty mesh.


Code :
Code: BlitzBasic
  1. ; These globals are used to return x, y, and z float values from functions.
  2. ; They must be accessed immediately after any function that uses them is called
  3. ; as they will be modified by other functions which use them.
  4. Global G_return_x#, G_return_y#, G_return_z#
  5.  
  6.  
  7. Function CenterMesh( mesh )
  8. ; Centers the vertex data of the specified mesh to be at the world center.
  9.  
  10. ; RETURNS:-
  11. ; The function returns the total number of vertices found in the mesh.
  12. ; If a zero is returned, then no vertices were found and the globals G_return_x#, G_return_y#, G_return_z#
  13. ; do not contain valid data, and should not be used for any purpose.
  14.  
  15. ; The original offset position of the mesh in the globals G_return_x#, G_return_y#, G_return_z#.
  16.  
  17. ; NOTES:-
  18. ; Requires the G_return_x#, G_return_y#, G_return_z# globals.
  19.  
  20. Local max_surface, max_vertex, surface, vertex, vx#, vy#, vz#, vertex_count
  21. Local px#, py#, pz#, nx#, ny#, nz#
  22.  
  23. ; Count the number of surfaces.
  24. max_surface = CountSurfaces ( mesh )
  25.  
  26. If max_surface ; If the mesh has surface data...
  27.  
  28.         ; Loop through all the surface indexes.
  29.         For surface_index = 1 To max_surface
  30.        
  31.                 ; Get the surface for the current surface index.
  32.                 surface = GetSurface ( mesh, surface_index )
  33.                
  34.                 ; Count the number of vertices.
  35.                 max_vertex = CountVertices ( surface )
  36.                
  37.                 ; Increment the count of all vertices found, so that it can be returned by the function.
  38.                 vertex_count = vertex_count + max_vertex
  39.                
  40.                 If max_vertex ; If the surface has vertex data...
  41.                
  42.                         ; Vertex indexes start at zero, so adjust max_vertex to suit.
  43.                         max_vertex = max_vertex - 1    
  44.                
  45.                         ; Seed min/max vertex variables.
  46.                         px# = VertexX# ( surface, 0 ) : nx# = px#
  47.                         py# = VertexY# ( surface, 0 ) : ny# = py#
  48.                         pz# = VertexZ# ( surface, 0 ) : nz# = pz#
  49.                
  50.                         ; Loop through all the vertex indexes.
  51.                         For vertex_index = 0 To max_vertex
  52.                        
  53.                                 ; Get the x, y, z position of the vertex.
  54.                                 vx# = VertexX# ( surface, vertex_index )
  55.                                 vy# = VertexY# ( surface, vertex_index )
  56.                                 vz# = VertexZ# ( surface, vertex_index )
  57.                                
  58.                                 ; Find the highest x, y, z vertex position values.
  59.                                 If vx# > px# Then px# = vx#
  60.                                 If vy# > py# Then py# = vy#
  61.                                 If vz# > pz# Then pz# = vz#
  62.                                
  63.                                 ; Find the lowest x, y, z vertex position values.
  64.                                 If vx# < nx# Then nx# = vx#
  65.                                 If vy# < ny# Then ny# = vy#
  66.                                 If vz# < nz# Then nz# = vz#
  67.                        
  68.                         Next
  69.                        
  70.                 EndIf
  71.        
  72.         Next
  73.        
  74.         ; Find the mid-point between the highest and lowest x, y, z vertex position values.
  75.         G_return_x# = ( px# + nx# ) / 2.0
  76.         G_return_y# = ( py# + ny# ) / 2.0
  77.         G_return_z# = ( pz# + nz# ) / 2.0
  78.        
  79.         ; Position the mesh data back to the world center.
  80.         PositionMesh mesh, -G_return_x#, -G_return_y#, -G_return_z#
  81.        
  82. EndIf
  83.  
  84. ; Return the total number of vertices found. If a zero is returned,
  85. ; then no vertices were found and the globals G_return_x#, G_return_y#, G_return_z#
  86. ; do not contain valid data, and should not be used for any purpose.
  87. Return vertex_count
  88.  
  89. End Function
  90.  
  91.  
  92. ; *** EXAMPLE ***
  93.  
  94.  
  95. Graphics3D 800, 600, 0, 2
  96. SetBuffer BackBuffer()
  97.  
  98. TurnEntity CreateLight(), 45.0, 0.0, 0.0
  99.  
  100. Global G_cam = CreateCamera()
  101. CameraZoom G_cam, 1.6
  102. MoveEntity G_cam, 0.0, 0.0, -20.0
  103.  
  104. ; Create a box to mark the world center.
  105. Global G_world_center_marker = CreateCube()
  106. ScaleEntity G_world_center_marker, 0.25, 0.25, 0.25
  107. EntityColor G_world_center_marker, 255, 0, 0
  108.  
  109. Global G_test_mesh = CreateCube()
  110. EntityAlpha G_test_mesh, 0.5
  111. PositionMesh G_test_mesh, 10.0, 10.0, 10.0
  112.  
  113. ; Create a box to mark the center of the test mesh.
  114. Global G_testmesh_center_marker = CreateCube()
  115. PositionEntity G_testmesh_center_marker, 10.0, 10.0, 10.0
  116. ScaleEntity G_testmesh_center_marker, 0.25, 0.25, 0.25
  117. EntityColor G_testmesh_center_marker, 0, 255, 0
  118.  
  119.  
  120. UpdateWorld : RenderWorld : Flip
  121.  
  122. Print "Press any key to center the mesh."
  123.  
  124. WaitKey
  125.  
  126. If CenterMesh( G_test_mesh ) = 0 Then Print "ERROR: No vertex data found." : WaitKey : End
  127.  
  128. UpdateWorld : RenderWorld : Flip
  129.  
  130. Print "Press any key to move the mesh back to its original position."
  131.  
  132. WaitKey
  133.  
  134. ; Position the G_test_mesh entity back where it was.
  135. PositionEntity G_test_mesh, G_return_x#, G_return_y#, G_return_z#
  136.  
  137. UpdateWorld : RenderWorld : Flip
  138.  
  139. Print "Press any key to continue."
  140.  
  141. WaitKey
  142.  
  143. While Not KeyDown( 1 )
  144.  
  145. If KeyDown( 205 )=True Then TurnEntity G_cam,0,-1,0
  146. If KeyDown( 203 )=True Then TurnEntity G_cam,0,1,0
  147. If KeyDown( 208 )=True Then MoveEntity G_cam,0,0,-0.05
  148. If KeyDown( 200 )=True Then MoveEntity G_cam,0,0,0.05
  149.  
  150. ; Use camera project to get 2D coordinates from 3D coordinates of cube
  151. CameraProject(G_cam,EntityX(G_test_mesh),EntityY(G_test_mesh),EntityZ(G_test_mesh))
  152.  
  153. RenderWorld
  154.  
  155. ; If cube is in view then draw text, if not then draw nothing otherwise text will be drawn at 0,0
  156. If EntityInView(G_test_mesh,G_cam)=True
  157.  
  158. ; Use ProjectedX() and ProjectedY() to get 2D coordinates from when CameraProject was used.
  159. ; Use these coordinates to draw text at a 2D position, on top of a 3D scene.
  160. Text ProjectedX#(),ProjectedY#(),"Test Mesh"
  161.  
  162. EndIf
  163.  
  164. Text 0,0,"Use cursor keys to move about"
  165. Text 0,20,"ProjectedX: "+ProjectedX#()
  166. Text 0,40,"ProjectedY: "+ProjectedY#()
  167. Text 0,60,"ProjectedZ: "+ProjectedZ#()
  168. Text 0,80,"EntityInView: "+EntityInView(G_test_mesh,G_cam)
  169. Text 0,100,"Tris Rendered: "+TrisRendered()
  170.  
  171. Flip
  172.  
  173. Wend
  174.  
  175. End


Comments :


Ross C(Posted 1+ years ago)

 Thanks Bill. It's alot more compact than my function(s) :)


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal