🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Explody

Published November 09, 2007
Advertisement
In response to this thread I started tinkering with using noise to generate explosion sprites. The result is here. It is a ZIP containing a program built on my codebase called framework.exe, and the good stuff is in the file explosion.lua. The EXE is a standalone Lua interpreter; run it and you get a command-line console. Execute the command dofile("explosion.lua") to setup for generating explosion frames. To construct a simple frame, call the function explosion_frame(tpower, rad, transx, transy, transz, densityscale, filename). The parameters are:

tpower -- The power of the turbulence applied to the explosion
rad -- The radius of the explosion. rad=1 will fill the frame, and possibly go beyond the edges
transx, transy, transz -- Offsets applied to the domains of the turbulence functions
densityscale -- Scale the explosion. Use a scale <1 for a cooler explosion, ==1 for a fully hot explosion frame

The explosion sprite frame will be output to the file filename in .TGA format as an RGBA sprite. Alpha fades out at the edges of the fireball.

There is also a convenience function for generating entire animated sequences of frames using interpolated spline curves. The animatable parameters are specified as splines, and interpolated in sequence, with the frames being spit out as a sequence: , ... where N is the number of frames.

Different results can be achieved by specifying curves for the different properties. This first image is a sequence animating the tpower value from 0 to 0.5, demonstrating how turbulence power affects the fireball. The greater the turbulence, the greater and more chaotic the flame spread:



This sequence details how changing the radius of the spherical function used as the basis of the fireball changes the size of the fireball, and can be used to animate the expansion:



This sequence details how animating the (transx,transy,transz) offset factors for the turbulence functions modifies the appearance of the fireball. Can be used to simulate roiling, turbulent, fluid flame:



And this final sequence shows how animating the densityscale property causes the flame to 'cool off' and dissipate. A scale of 1 makes a fully hot flame, tending toward 0 cools it toward the black and transparent end of the scale:



By combining animations of all these properties through experimentation, a full sequence of explosion from ignition through fireball to cooling incandescent gas can be simulated. The color scale used to color the fireball is found in the file explosioncolorscale.lua and can be tweaked as you see fit. It constructs the global spline curve called cs used by the explosion frame functions, constructing the curve from the table specified in the file. If you do tweak the curve, you can clear a curve's points using the clear() method.

To setup some curves for the animated sequence, you can build them in this fashion:

turbcurve = CCurvef()       -- Floating point curvescalecurve = CCurvef()      -- Floating point curveradcurve = CCurvef()        -- Floating point curvetranscurve = CCurvergbf()   -- 3-component floating point curve-- Animate turbulence from 0.25 to 0.5turbcurve:pushPoint(0.25)turbcurve:pushPoint(0.5)-- Animate radius from 0.5 to 1.0radcurve:pushPoint(0.5)radcurve:pushPoint(1.0)-- Animate scale through a broader curve from 1 to 0.1scalecurve:pushPoint(1)scalecurve:pushPoint(1)scalecurve:pushPoint(0.75)scalecurve:pushPoint(0.25)scalecurve:pushPoint(0.1)-- Animate turbulence through a small intervaltranscurve:pushPoint(CRGBf(0,0,0))transcurve:pushPoint(CRGBf(0.2,0.2,0.2))-- now, generate a sequence of frames.explosion_curve("explode", 10, turbcurve, radcurve, transcurve, scalecurve)


The result should be 10 .TGA files named explode1.tga through explode10.tga in the base directory. Open them up in the Gimp to see the progression. If you want to tweak during runtime, the various curves can be cleared with clear() method and repopulated using pushPoint(). There are certainly ways to improve the process, this is just the result of a couple evenings spent experimenting.

In particular, you can edit the way the explosion density function is constructed. In the LUA file, it is simply set up as a hierarchy of noise modules chained together, starting with a simple sphere, applying turbulence and scaling modules, etc... By using different basis functions for the sphere and the turbulence, vastly different effects can be applied. In the file noise.txt is a brief, crude description of the tool's generator capabilities. The noise generator system is based on the system used in libnoise, but heavily modified for greater flexibility in choice of basis functions.

You can also edit the color scale to be more to your liking. This one was cobbled together in a couple minutes by sampling an image constructed using the Gimp's gradient fill, using a custom gradient I whipped together. I'm not entirely satisfied with how it alpha fades at the black end, so it could use some tweaking.

Good luck, and enjoy.
Previous Entry Hat
Next Entry More explody
0 likes 9 comments

Comments

_the_phantom_
You sir, are many shades of awesome!
November 10, 2007 08:23 AM
Geometrian
I tried:
explosion_frame(1, 0.5, 0, 0, 0, 0.5, "1.tga")
which works, but I can't figure out how to get it to do multiple frames?
November 10, 2007 09:24 AM
JTippetts
You have to use the explosion_curve(prefix, numframes, turbtable, radtable, transtable, scaletable) function to actually generate multiple sequential frames. explosion_frame just grabs a single frame with set values; explosion_curve interpolates a set of spline curves in N steps to generate the frame values. The source snippet in the original post demonstrates constructing and populating the splines.
November 10, 2007 09:34 AM
JTippetts
Quote: Original post by phantom
You sir, are many shades of awesome!


[grin]
November 10, 2007 09:35 AM
Geometrian
I got explosion_sequence() to work!
I couldn't get explosion_curve().
What's the difference?
November 10, 2007 11:00 AM
JTippetts
Just a quick one here:



turbulence spline points: {0.35, 0.45}
radius spline points: {0.75, 0.75, 0.8, 1.0}
scale spline points: {0.75, 1.0, 1.0, 0.5, 0.1}
translation spline points:{(0.1,0.1,0.1), (0.2,0.2,0.2)}

Obviously lots of room for tweaking, but still kinda cool.
November 10, 2007 11:43 AM
JTippetts
Quote: Original post by Geometrian
I got explosion_sequence() to work!
I couldn't get explosion_curve().
What's the difference?


Post your code. explosion_sequence only allows interpolation between two points per quantity, start and end. For explosion_curve you specify curves of arbitrary shape for each quantity for tighter control over the animation. You can keep the fireball hot until a very brief fade at the end, keep the radius the same until a brief expansion at the end, etc... Much easier to control the final animation.
November 10, 2007 11:48 AM
Geometrian
for instance:
explosion_curve("explosion1", 3, [0,0,0], [1,1,1], [[0,0,0],[0,0,0],[0,0,0]], [1,1,1])
doesn't work.
November 10, 2007 01:15 PM
JTippetts
Curves are C++ objects initialized with points and passed to the function, not Lua tables. There is a function that can do frames from a Lua table called explosion_table, but I haven't actually even tried it yet.

To use the curve function, you have to setup your curves separately:


turbcurve=CCurvef()
radcurve=CCurvef()
scalecurve=CCurvef()
transcurve=CCurvergbf()


Then populate the curves with the control points for you spline. turb, scale and radius are floating point curves, so points passed to it consist of single float values. trans is a 3-component floating point curve; since I am currently in the process of revamping my curve systems, for this experiment I had to hijack CCurvergbf for my purposes. To populate it, you need to push points of CRGBf format (more consistent naming conventions is part of the ongoing revamp).

So, for example:


turbcurve:pushPoint(0.35)
turbcurve:pushPoint(0.45)

scalecurve:pushPoint(0.75)
scalecurve:pushPoint(1)
scalecurve:pushPoint(1)
scalecurve:pushPoint(0.5)
scalecurve:pushPoint(0.1)

radcurve:pushPoint(1)
radcurve:pushPoint(1)

transcurve:pushPoint(CRGBf(0,0,0))
transcurve:pushPoint(CRGBf(0,0,0))

explosion_curve("blargh", 10, turbcurve, radcurve, transcurve, scalecurve)


This would animate turbulence from 0.35 to 0.45 and scale(color) through a brief opening flash from 0.75 to 1, then a slightly more gradual cooling down to 0.1. Radius would stay constant, and there would be no animation of turbulence. To animate turbulence and radius, different points for transcurve and scalecurve would be chosen.

To repopulate a curve, call the curve's clear() method, then push the new points.
November 10, 2007 01:29 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement