home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / CODE_UPLOAD1274612162000.psc / Sphere.cls < prev   
Encoding:
Visual Basic class definition  |  2000-12-16  |  7.2 KB  |  260 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "Sphere"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. ' Sphere
  17.  
  18. Implements RayTraceable
  19.  
  20. ' Position
  21. Private Center As Point3D
  22. ' Radius
  23. Private Radius As Single
  24.  
  25. ' Lighting values:
  26. ' Ambient:
  27. Private AmbKr As Single
  28. Private AmbKg As Single
  29. Private AmbKb As Single
  30. ' Diffuse
  31. Private DiffKr As Single
  32. Private DiffKg As Single
  33. Private DiffKb As Single
  34. ' Specular
  35. Private Spec_K As Single
  36. Private Spec_N As Single
  37. ' Reflected factor
  38. Private ReflKr As Single
  39. Private ReflKg As Single
  40. Private ReflKb As Single
  41.  
  42. ' Culling values
  43. ' True if we had a hit on this scanline
  44. Private HadHit As Boolean
  45. ' True if we had a hit on previous scanline
  46. Private HadHitPrev As Boolean
  47. ' True if we are culled forever
  48. Private ForeverCulled As Boolean
  49. ' True if we are done on this scanline
  50. Private ScanlineDone As Boolean
  51.  
  52. Public Sub RayTraceable_CullScanline(ByVal px As Single, ByVal py As Single, ByVal pz As Single, ByVal Nx As Single, ByVal Ny As Single, ByVal Nz As Single)
  53.     Dim Dx As Single
  54.     Dim Dy As Single
  55.     Dim Dz As Single
  56.     Dim Dist As Single
  57.     
  58.     ' Don't run this sub if we are culled forever
  59.     If ForeverCulled Then
  60.         ScanlineDone = True
  61.         Exit Sub
  62.     End If
  63.     
  64.     ' We have not had a hit already
  65.     HadHit = False
  66.     
  67.     ' Find the distance from the center of the
  68.     ' sphere to the scanline plane.
  69.  
  70.     ' Get the vector from our center to the point.
  71.     With Center
  72.         Dx = .Trans(1) - px
  73.         Dy = .Trans(2) - py
  74.         Dz = .Trans(3) - pz
  75.     End With
  76.  
  77.     ' Take the dot product of this and the normal.
  78.     ' If the resulting distance > Radius, cull.
  79.     ScanlineDone = (Abs(Dx * Nx + Dy * Ny + Dz * Nz) > Radius)
  80.  
  81.     ' See if we will be culled in the future.
  82.     If ScanlineDone Then
  83.         ' We were not culled on a previous scanline
  84.         ' but we are now. We will be culled on
  85.         ' all later scanlines.
  86.         If HadHitPrev Then ForeverCulled = True
  87.     Else
  88.         ' We are not culled
  89.         HadHitPrev = True
  90.     End If
  91. End Sub
  92.  
  93. Public Function RayTraceable_FindT(DirectC As Boolean, px As Single, py As Single, pz As Single, Vx As Single, Vy As Single, Vz As Single) As Single
  94.     Dim A As Single
  95.     Dim B As Single
  96.     Dim C As Single
  97.     Dim B24AC As Single
  98.     Dim t1 As Single
  99.     Dim t2 As Single
  100.     Dim Cx As Single
  101.     Dim Cy As Single
  102.     Dim Cz As Single
  103.     
  104.     ' Check if we are culled
  105.     If DirectC And ScanlineDone Then
  106.         RayTraceable_FindT = -1
  107.         Exit Function
  108.     End If
  109.     
  110.     ' Create values for the center of the sphere
  111.     Cx = Center.Trans(1)
  112.     Cy = Center.Trans(2)
  113.     Cz = Center.Trans(3)
  114.     
  115.     ' Get coefficients for the quadratic
  116.     A = Vx * Vx + Vy * Vy + Vz * Vz
  117.     B = 2 * Vx * (px - Cx) + _
  118.         2 * Vy * (py - Cy) + _
  119.         2 * Vz * (pz - Cz)
  120.     C = Cx * Cx + Cy * Cy + Cz * Cz + _
  121.         px * px + py * py + pz * pz - _
  122.         2 * (Cx * px + Cy * py + Cz * pz) - _
  123.         Radius * Radius
  124.         
  125.     ' Solve the quadratic A * t ^ 2 + B * t + C = 0
  126.     B24AC = B * B - 4 * A * C
  127.     
  128.     ' Check intersections
  129.     If B24AC < 0 Then
  130.         ' No real intersection
  131.         If HadHit And DirectC Then ScanlineDone = True
  132.         RayTraceable_FindT = -1
  133.         Exit Function
  134.     ElseIf B24AC = 0 Then
  135.         ' One intersection
  136.         t1 = -B / 2 / A
  137.     Else
  138.         ' Two intersections
  139.         B24AC = Sqr(B24AC)
  140.         t1 = (-B + B24AC) / 2 / A
  141.         t2 = (-B - B24AC) / 2 / A
  142.         ' Use only positive values for t
  143.         If t1 < 0.01 Then t1 = t2
  144.         If t2 < 0.01 Then t2 = t1
  145.         ' Use the smallest one
  146.         If t1 > t2 Then t1 = t2
  147.     End If
  148.     
  149.     ' If there's no positive value, there's no intersection
  150.     If t1 < 0.01 Then
  151.         If HadHit And DirectC Then ScanlineDone = True
  152.         RayTraceable_FindT = -1
  153.         Exit Function
  154.     End If
  155.     ' If the function reaches this line, we had a hit
  156.     If DirectC Then HadHit = True
  157.     RayTraceable_FindT = t1
  158. End Function
  159.  
  160. Public Sub RayTraceable_FindHitColor(Objects As Collection, _
  161.     ByVal eyeX As Single, ByVal eyeY As Single, ByVal eyeZ As Single, _
  162.     ByVal px As Single, ByVal py As Single, ByVal pz As Single, _
  163.     ByRef R As Integer, ByRef G As Integer, ByRef B As Integer)
  164.     
  165.     Dim Nx As Single
  166.     Dim Ny As Single
  167.     Dim Nz As Single
  168.     Dim Nlen As Single
  169.     
  170.     ' Find the unit normal
  171.     Nx = px - Center.Trans(1)
  172.     Ny = py - Center.Trans(2)
  173.     Nz = pz - Center.Trans(3)
  174.     Nlen = Sqr(Nx * Nx + Ny * Ny + Nz * Nz)
  175.     Nx = Nx / Nlen
  176.     Ny = Ny / Nlen
  177.     Nz = Nz / Nlen
  178.     ' Uncomment the following lines for normal
  179.     ' vector perturbation (bumpiness)
  180.     ' Nx = Nx + Rnd * 0.2
  181.     ' Ny = Ny + Rnd * 0.2
  182.     ' Nz = Nz + Rnd * 0.2
  183.     ' Nlen = Sqr(Nx * Nx + Ny * Ny + Nz * Nz)
  184.     ' Nx = Nx / Nlen
  185.     ' Ny = Ny / Nlen
  186.     ' Nz = Nz / Nlen
  187.     
  188.     ' Calculate hit color
  189.     CalculateHitColor Objects, Me, eyeX, eyeY, eyeZ, _
  190.         px, py, pz, _
  191.         Nx, Ny, Nz, _
  192.         DiffKr, DiffKg, DiffKb, _
  193.         AmbKr, AmbKg, AmbKb, _
  194.         Spec_K, Spec_N, _
  195.         ReflKr, ReflKg, ReflKb, _
  196.         R, G, B
  197. End Sub
  198.  
  199. Public Sub RayTraceable_Apply(M() As Single)
  200.     m3Apply Center.Coord, M, Center.Trans
  201. End Sub
  202.  
  203. Public Sub RayTraceable_ApplyFull(M() As Single)
  204.     m3ApplyFull Center.Coord, M, Center.Trans
  205. End Sub
  206.  
  207. Public Sub SetValues(ByVal X As Single, ByVal Y As Single, ByVal Z As Single, _
  208.     ByVal Rad As Single, _
  209.     ByVal AmbientKr As Single, ByVal AmbientKg As Single, ByVal AmbientKb, _
  210.     ByVal DiffuseKr As Single, ByVal DiffuseKg As Single, ByVal DiffuseKb, _
  211.     ByVal SpecularK As Single, ByVal SpecularN As Single, _
  212.     ByVal ReflectedKr As Single, ByVal ReflectedKg As Single, ByVal ReflectedKb As Single)
  213.     
  214.     ' Assign values to local variables
  215.     ' Position and radius
  216.     Center.Coord(1) = X
  217.     Center.Coord(2) = Y
  218.     Center.Coord(3) = Z
  219.     Center.Coord(4) = 1#
  220.     Radius = Rad
  221.     
  222.     ' Lighting
  223.     ' Ambient
  224.     AmbKr = AmbientKr
  225.     AmbKg = AmbientKg
  226.     AmbKb = AmbientKb
  227.     ' Diffuse
  228.     DiffKr = DiffuseKr
  229.     DiffKg = DiffuseKg
  230.     DiffKb = DiffuseKb
  231.     ' Specular
  232.     Spec_K = SpecularK
  233.     Spec_N = SpecularN
  234.     ' Reflected
  235.     ReflKr = ReflectedKr
  236.     ReflKg = ReflectedKg
  237.     ReflKb = ReflectedKb
  238. End Sub
  239.  
  240. Public Sub RayTraceable_GetRminRmax(new_min As Single, new_max As Single, ByVal X As Single, ByVal Y As Single, ByVal Z As Single)
  241.     Dim Dx As Single
  242.     Dim Dy As Single
  243.     Dim Dz As Single
  244.     Dim Dist As Single
  245.  
  246.     Dx = X - Center.Trans(1)
  247.     Dy = Y - Center.Trans(2)
  248.     Dz = Z - Center.Trans(3)
  249.     Dist = Sqr(Dx * Dx + Dy * Dy + Dz * Dz)
  250.     new_max = Dist + Radius
  251.     new_min = Dist - Radius
  252.     If new_min < 0 Then new_min = 0
  253. End Sub
  254.  
  255. Public Sub RayTraceable_ResetCulling()
  256.     ForeverCulled = False
  257.     HadHitPrev = False
  258. End Sub
  259.  
  260.