home *** CD-ROM | disk | FTP | other *** search
- VERSION 1.0 CLASS
- BEGIN
- MultiUse = -1 'True
- END
- Attribute VB_Name = "ObjPlane"
- Attribute VB_Creatable = False
- Attribute VB_Exposed = False
- Option Explicit
-
- Private Point1 As Point3D ' Point on plane.
- Private Point2 As Point3D ' Normal = P2 - P1.
-
- Private HitX As Single
- Private HitY As Single
- Private HitZ As Single
-
- Private Kar As Single
- Private Kag As Single
- Private Kab As Single
-
- Private Kdr As Single
- Private Kdg As Single
- Private Kdb As Single
-
- Private SpecN As Single
- Private Ks As Single
-
- ' ************************************************
- ' Apply a transformation matrix to the plane.
- ' ************************************************
- Public Sub Apply(M() As Single)
- ' Transform the point and normal.
- m3Apply Point1.coord, M, Point1.trans
- m3Apply Point2.coord, M, Point2.trans
- End Sub
- ' ************************************************
- ' Return the red, green, and blue components of
- ' the surface at the hit position.
- ' ************************************************
- Public Sub HitColor(Objects As Collection, R As Integer, G As Integer, B As Integer)
- Dim nx As Single
- Dim ny As Single
- Dim nz As Single
- Dim lx As Single
- Dim ly As Single
- Dim lz As Single
- Dim Vx As Single
- Dim Vy As Single
- Dim Vz As Single
- Dim rx As Single
- Dim ry As Single
- Dim rz As Single
- Dim n_len As Single
- Dim l_len As Single
- Dim v_len As Single
- Dim r_len As Single
- Dim NdotL As Single
- Dim RdotV As Single
- Dim NdotV As Single
- Dim r_dif As Single
- Dim g_dif As Single
- Dim b_dif As Single
- Dim r_amb As Single
- Dim g_amb As Single
- Dim b_amb As Single
- Dim spec As Single
- Dim i As Integer
- Dim dist As Single
- Dim shadowed As Boolean
-
- ' Find the unit vector pointing toward the light.
- lx = LightSource.trans(1) - HitX
- ly = LightSource.trans(2) - HitY
- lz = LightSource.trans(3) - HitZ
- l_len = Sqr(lx * lx + ly * ly + lz * lz)
- lx = lx / l_len
- ly = ly / l_len
- lz = lz / l_len
- ' We will use l_len later as the distance from
- ' the light to the surface.
-
- ' Find the surface unit normal.
- nx = Point2.trans(1) - Point1.trans(1)
- ny = Point2.trans(2) - Point1.trans(2)
- nz = Point2.trans(3) - Point1.trans(3)
- n_len = Sqr(nx * nx + ny * ny + nz * nz)
- nx = nx / n_len
- ny = ny / n_len
- nz = nz / n_len
-
- ' Find the vector V from the surface to the
- ' viewpoint.
- Vx = EyeX - HitX
- Vy = EyeY - HitY
- Vz = EyeZ - HitZ
- v_len = Sqr(Vx * Vx + Vy * Vy + Vz * Vz)
- Vx = Vx / v_len
- Vy = Vy / v_len
- Vz = Vz / v_len
-
- ' See if the light shines on the back of the
- ' plane. I.e. if the center of projection
- ' and light source lie on the same side.
- NdotL = nx * lx + ny * ly + nz * lz
- NdotV = nx * Vx + ny * Vy + nz * Vz
- shadowed = (NdotL * NdotV < 0)
-
- ' See if the light shines directly on the surface.
- If Not shadowed Then
- For i = 1 To Objects.Count
- dist = Objects.Item(i).RayDistance( _
- LightSource.trans(1), _
- LightSource.trans(2), _
- LightSource.trans(3), _
- -lx, -ly, -lz)
- If dist < l_len - 0.1 Then Exit For
- Next i
- shadowed = (i <= Objects.Count)
- End If
-
- ' Calculate the part due to diffuse reflection.
- If shadowed Then
- ' The light does not hit the surface.
- r_dif = 0
- g_dif = 0
- b_dif = 0
- spec = 0
- Else
- ' Treat backface planes as normal planes.
- NdotL = Abs(NdotL)
-
- r_dif = Kdr * NdotL
- g_dif = Kdg * NdotL
- b_dif = Kdb * NdotL
-
- ' Find vector R in the mirror direction.
- rx = 2 * nx * NdotL - lx
- ry = 2 * ny * NdotL - ly
- rz = 2 * nz * NdotL - lz
-
- ' Calculate the part due to specular reflection.
- RdotV = rx * Vx + ry * Vy + rz * Vz
- If RdotV < 0 Then
- spec = 0
- Else
- spec = Ks * RdotV ^ SpecN
- End If
- End If
-
- ' Calculate the part due to ambient light.
- r_amb = LightIar * Kar
- g_amb = LightIag * Kag
- b_amb = LightIab * Kab
-
- ' See how intense to make the color.
- R = r_amb + _
- LightIir / (l_len + LightKdist) * _
- (r_dif + spec)
- G = g_amb + _
- LightIig / (l_len + LightKdist) * _
- (g_dif + spec)
- B = b_amb + _
- LightIib / (l_len + LightKdist) * _
- (b_dif + spec)
- End Sub
-
- ' ************************************************
- ' Compute the distance from point (px, py, pz)
- ' along vector <vx, vy, vz> to the plane.
- '
- ' Save the point of intersection in
- ' (HitX, HitY, HitZ) for later use.
- ' ************************************************
- Public Function RayDistance(px As Single, py As Single, pz As Single, Vx As Single, Vy As Single, Vz As Single) As Single
- Dim A As Single
- Dim B As Single
- Dim C As Single
- Dim D As Single
- Dim nx As Single
- Dim ny As Single
- Dim nz As Single
- Dim denom As Single
- Dim t As Single
-
- ' Recompute the normal vector.
- nx = Point2.trans(1) - Point1.trans(1)
- ny = Point2.trans(2) - Point1.trans(2)
- nz = Point2.trans(3) - Point1.trans(3)
-
- ' Compute the plane's parameters.
- A = nx
- B = ny
- C = nz
- D = -(nx * Point1.trans(1) + _
- ny * Point1.trans(2) + _
- nz * Point1.trans(3))
-
- ' If the denominator = 0, the ray is parallel
- ' to the plane so there's no intersection.
- denom = A * Vx + B * Vy + C * Vz
- If denom = 0 Then
- RayDistance = INFINITY
- Exit Function
- End If
-
- ' Solve for t.
- t = -(A * px + B * py + C * pz + D) / denom
-
- ' If t < 0 then the intersection is behind the
- ' center of projection so not of interest.
- If t < 0 Then
- RayDistance = INFINITY
- Exit Function
- End If
-
- ' Compute the actual hit location.
- HitX = px + t * Vx
- HitY = py + t * Vy
- HitZ = pz + t * Vz
-
- ' Compute the distance from (px, py, pz).
- A = px - HitX
- B = py - HitY
- C = pz - HitZ
- RayDistance = Sqr(A * A + B * B + C * C)
- End Function
-
- ' ************************************************
- ' Set the points. Point2 = Point1 + normal vector.
- ' ************************************************
- Public Sub Initialize(Cx As Single, Cy As Single, Cz As Single, Vx As Single, Vy As Single, Vz As Single)
- Point1.coord(1) = Cx
- Point1.coord(2) = Cy
- Point1.coord(3) = Cz
- Point1.coord(4) = 1
- Point2.coord(1) = Cx + Vx
- Point2.coord(2) = Cy + Vy
- Point2.coord(3) = Cz + Vz
- Point2.coord(4) = 1
- End Sub
-
-
- ' ************************************************
- ' Set N and Ks for specular reflection.
- ' ************************************************
- Sub SetSpec(n As Single, s As Single)
- SpecN = n
- Ks = s
- End Sub
-
- ' ************************************************
- ' Return the latest Hit location.
- ' ************************************************
- Public Sub HitLocation(x As Single, y As Single, z As Single)
- x = HitX
- y = HitY
- z = HitZ
- End Sub
-
- ' ************************************************
- ' Set constants for diffuse reflection.
- ' ************************************************
- Sub SetKd(R As Single, G As Single, B As Single)
- Kdr = R
- Kdg = G
- Kdb = B
- End Sub
-
- ' ************************************************
- ' Set constants for ambient light.
- ' ************************************************
- Sub SetKa(R As Single, G As Single, B As Single)
- Kar = R
- Kag = G
- Kab = B
- End Sub
-
-
-
-