• 10/24/01 05:17 PM
    Sign in to follow this  

    Lightning

    Graphics and GPU Programming

    Myopic Rhino
    [center][attachment=3629:image001.png]
    [/center]
    [size="5"][b]1.0 Abstract[/b][/size]

    One night when there was a lightning storm (2 or 3 nights ago) I decided I would write an article on lightning just for fun. This is the first time I have ever tried to simulate lightning before. If there are any spelling mistakes or similar please E-Mail then to me at [email="javaman@telusplanet.net"]javaman@telusplanet.net[/email].

    [size="3"][b]1.1 About this Article[/b][/size]

    All the demo code is in Visual Basic with DirectX8. There is a demo with code and exe that you can via the attached article resource.


    [size="5"][b]2.0 Getting down to work[/b][/size]

    First off, you just set up a normal Direct3D scene. I added a bit of fog to make it look like it's raining, but you don't have to do this if you don't want to.

    Enough of that on with the fun. I use 2 classes in this method: the first you only need on ref to its name is "clsLighteningBoltMain". It's more or less just a container class for the second class called "clsLighteningBolt".

    [size="3"][b]2.1 clsLighteningBoltMain[/b][/size]

    [b]Class variables[/b]

    [indent][code]Private BoltArray as clsLighteningBolt[/code][/indent] This is the head of are singly linked list

    [b]Functions[/b]

    [indent][code]Public Function Get_YfromXZ(ByVal X as single, ByVal Z as single) as Single[/code][/indent] This function returns the height of the ground at X, Z. (Note: This function only returns 0 because our ground is flat)

    [indent][code]Public Sub AddBolt(ByVal X as single, ByVal Y as single, _
    ByVal Z as single, ByVal lColor as single)[/code][/indent] This sub adds a bolt to the list at the starting pos of X, Y, Z with the color lColor (Note: for some unknown reason color is not working; if any one finds out why please e-mail me)

    [indent][code]Public Sub DrawBolts()[/code][/indent] This sub draws the bolt list and removes any bolts that say they can be removed.

    [size="3"][b]2.2 clsLighteningBolt[/b][/size]

    [b]Variables[/b]

    [indent][code]Public iNext as clsLighteningBolt[/code][/indent] Pointer to the next bolt in the list

    [indent][code]Public Parent as clsLighteningBoltMain[/code][/indent] Pointer to the container class (so we can call Get_YFromXZ)

    [b]Functions[/b]

    [indent][code]Public Sub Init_Bolt(ByVal X as single, ByVal Y as single, _
    ByVal Z as Single, iColor as Long)[/code][/indent] Sets the bolt startup values

    [indent][code]Public Function Draw_Bolt() as Boolean[/code][/indent] Draws the bolt and returns false if it's done (e.g. hit the ground)

    [size="3"][b]2.3 How the code works[/b][/size]

    [b]2.3.1 clsLighteningMain[/b]

    [b]Get_YFromXZ[/b]

    This function returns the height of the ground/strike plane at position (x, z).

    [indent][code]Public Function Get_YFromXZ(ByVal x As Single, _
    ByVal z As Single) As Single
    Get_YFromXZ = 0


    End Function[/code][/indent] [b]AddBolt[/b]

    This sub adds a bolt to the start of the bolt list with the specified position and color.

    [indent][code]Public Sub AddBolt(ByVal x As Single, ByVal y As Single, _
    ByVal z As Single, lColor As Long)
    Dim NewBolt As New clsLighteningBolt
    NewBolt.Init_Bolt x, y, z, lColor
    Set NewBolt.iNext = BoltArray
    Set BoltArray = NewBolt
    Set NewBolt.Parent = Me
    End Sub[/code][/indent][b] DrawBolts[/b]

    This sub draws all of the bolts in the bolt list and removes bolts that have hit the ground.

    [indent][code]Public Sub DrawBolts()
    Dim Curr As clsLighteningBolt
    Dim Last As clsLighteningBolt

    Device.SetVertexShader FVF_LineVertex

    Set Curr = BoltArray
    Device.SetTexture 0, Nothing



    Do
    If Curr Is Nothing Then Exit Do
    If Curr.Draw_Bolt() = False Then
    If Not Last Is Nothing Then
    Set Last.iNext = Curr.iNext
    Set Curr = Curr.iNext
    Else
    Set BoltArray = Curr.iNext
    Set Curr = BoltArray
    End If
    Else
    Set Last = Curr
    Set Curr = Curr.iNext
    End If


    Loop
    End Sub[/code][/indent] [b]2.3.2 clsLighteningBolt[/b]

    [b] InitBolt[/b]

    This sub just sets the first line segment up.

    [indent][code]Public Sub Init_Bolt(ByVal x As Single, ByVal y As Single, ByVal z As Single, ByVal iColor As Long)
    ReDim Lines(1)
    NumberLines = 1
    With Lines(0)
    .x = x
    .y = y
    .z = z
    .Color = iColor
    End With

    With Lines(1)
    .x = x


    .y = y - 0.06
    .z = z
    .Color = iColor
    End With
    End Sub[/code][/indent][b] DrawBolt[/b]

    This sub draws and adds one more vertex to the line strip and returns true if its not done yet and false if it is.

    [indent][code]Public Function Draw_Bolt() As Boolean
    NumberLines = NumberLines + 1
    ReDim Preserve Lines(NumberLines)
    With Lines(NumberLines)


    .x = Lines(NumberLines - 1).x + (1 - Rnd * 2) * 0.3


    .y = Lines(NumberLines - 1).y - (Rnd + 0.55)


    .z = Lines(NumberLines - 1).z + (1 - Rnd * 2) * 0.3


    .Color = Lines(0).Color
    End With

    Device.DrawPrimitiveUP
    D3DPT_LINESTRIP,NumberLines, Lines(0),_
    Length_LineVertex

    Draw_Bolt = True
    If Lines(NumberLines).y <= Parent.Get_YFromXZ(Lines(1).x, Lines(1).z) Then
    If Rnd > 0.95 Then
    Draw_Bolt = False
    End If
    End If
    End Function[/code][/indent]
    [size="5"][b]3.0 Theory[/b][/size]

    [size="3"][b]3.1 How it works[/b][/size]

    The way this works is really simple when you think about it. There is a list of all the bolts that this container needs to think about. You add and remove bolts from there. Here's a picture to help out with this one:

    [b]Adding a new bolt[/b]

    [b] Step One:[/b]

    [attachment=3630:lstStepOne.jpg]

    Create a new bolt class and set its variables.

    [b] Step 2:[/b]

    [attachment=3631:lstStepTwo.jpg]

    Insert the new bolt into the list right after the head.

    [b] Removing a bolt[/b]

    [attachment=3632:lstRemoveStepOne.jpg]

    Steps:
    [list=1][*]Set 1.iNext = 2.iNext[*]Set 2.iNext = Nothing[*]Set 2 = Nothing[/list] Figuring out where to put the next vertex for a bolt is even easier then that. Here's how:
    [list=1][*]Resize the Vertex array so you can fit one more vertex in it[*]Set the X to X(index-1) + 1-(rnd * 2) * 0.3 and same for the z coordint[*]Set y to Y(index-1) - (rnd + .55)[/list] Now last but not least: drawing the bolt. I do it with DirectX using a line strip.

    [indent][code]Device.DrawPrimitiveUP D3DPT_LINESTRIP, Ubound(Lines()), _
    Lines(0),16[/code][/indent]
    [size="5"][b]4.0 Conclusion[/b][/size]

    Well that's all there is to it. Not hard, is it?

    WepPage: [url="http://www.telusplanet.net/public/javaman/"]http://www.telusplan...public/javaman/[/url]

    E-Mail: [email="javaman@telusplanet.net"]javaman@telusplanet.net[/email]


      Report Article
    Sign in to follow this  


    User Feedback

    Create an account or sign in to leave a review

    You need to be a member in order to leave a review

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    There are no reviews to display.