proc AddGradient (c1, c2, n : int)
var clr : int
var r1, g1, b1, r2, g2, b2, p, p0 : real
RGB.GetColor (c1, r1, g1, b1)
RGB.GetColor (c2, r2, g2, b2)
const a := 50
for i : 1 .. n
p := (i / n) * 100
p0 := 100 - p
clr := RGB.AddColor ((((r1 * p) + (r2 * p0)) / 2) / a, (((g1 * p) + (g2 * p0)) / 2) / a, (((b1 * p) + (b2 * p0)) / 2) / a)
end for
end AddGradient
class ParticleSysRec3D
export Init, resetX, resetY, resetZ, forceX, forceY, forceZ
var resetX, resetY, resetZ, forceX, forceY, forceZ : real
proc Init (rx, ry, rz, fx, fy, fz : real)
resetX := rx
resetY := ry
resetZ := rz
forceX := fx
forceY := fy
forceZ := fz
end Init
end ParticleSysRec3D
class Particle3D
import ParticleSysRec3D
export Init, DrawParticle, Run, LoadSystemVars, ReInit, GetLife
var x, y, z, xv, yv, zv, radius, mass, maxLife, life : real
var xD, yD, c : int
var picFlag : boolean := false
var pWidth, pHeight : int
var resetX, resetY, resetZ, forceX, forceY, forceZ, inter : real
var totalV, Vx, Vy, Vz : real
var Camx, Camy, Camz : real := maxx div 2
var CamzFrame : real := 0
function GetLife : real
result life
end GetLife
proc LoadSystemVars (s : ^ParticleSysRec3D)
resetX := s -> resetX
resetY := s -> resetX
resetZ := s -> resetZ
forceX := s -> forceX
forceY := s -> forceY
forceZ := s -> forceZ
end LoadSystemVars
proc Init (X, Y, Z, XV, YV, ZV, RAD, MASS, LIFE, MLIFE, INT : real, C : int, PIC : boolean)
x := X
y := Y
z := Z
xv := XV
yv := YV
zv := ZV
radius := RAD
mass := MASS
life := LIFE
maxLife := MLIFE
c := C
inter := INT
picFlag := PIC
if picFlag then
pWidth := Pic.Width (c) div 2
pHeight := Pic.Height (c) div 2
end if
end Init
proc ReInit (X, Y, Z, XV, YV, ZV, LIFE, MLIFE : real)
x := X
y := Y
z := Z
xv := XV
yv := YV
zv := ZV
maxLife := MLIFE
life := LIFE
end ReInit
var hold : real
const a:=2
proc DrawParticle
if z < Camz then
xD := round ((CamzFrame - (z - (((z - Camz) / ((x - Camx) + 0.001)) * x))
/ ((z - Camz) / ((x - Camx) + 0.001))))
yD := round ((CamzFrame * ((y - Camy) / ((z - Camz) + 0.001))) + (y -
(((y - Camy) / ((z - Camz) + 0.001)) * z)))
hold := ((Camx - x) ** 2 + (Camy - y) ** 2 + (Camz - z) ** 2) ** 0.5
drawfilloval (xD, yD, round (radius / hold * 640 / a), round (radius / hold * 640 / a), round (((life / maxLife) * 255) + 255))
end if
end DrawParticle
proc CalcVect
totalV := (xv ** 2 + yv ** 2 + zv ** 2) ** 0.5
Vx := xv / totalV
Vy := yv / totalV
Vz := zv / totalV
end CalcVect
proc ReCalcVect
xv := totalV * Vx
yv := totalV * Vy
zv := totalV * Vz
end ReCalcVect
proc Run
CalcVect
xv += forceX
yv += forceY
zv += forceZ
x += xv
y += yv
z += zv
life -= inter
end Run
end Particle3D
class ParticleSystem3D
import Particle3D, ParticleSysRec3D
export Default, InitSystem, InitVectRand, InitBaseVect, InitPosRand, Update, DrawSystem,
SetReset
var Default : ^ParticleSysRec3D
new Default
var maxParticles, LifeC : int := 2
var sourceX, sourceY, sourceZ, forceX, forceY, forceZ, maxLife, baseXv, baseYv, baseZv, baseXv0, baseYv0, baseZv0 : real
var rpRealModX, rpRealModY, rpRealModZ, rvMinX, rvMinY, rvMinZ, rvMaxX, rvMaxY, rvMaxZ, rvRealModX, rvRealModY, rvRealModZ, rpMinX, rpMinY, rpMinZ, rpMaxX, rpMaxY, rpMaxZ : real
var ParticleSys : flexible array 1 .. 1 of ^Particle3D
proc InitVectRand (rrmx, rrmy, rrmz, rminx, rmaxx, rminy, rmaxy, rminz, rmaxz : real)
rvRealModX := rrmx
rvRealModY := rrmy
rvRealModZ := rrmz
rvMinX := rminx
rvMaxX := rmaxx
rvMinY := rminy
rvMaxY := rmaxy
rvMinZ := rminz
rvMaxZ := rmaxz
end InitVectRand
proc InitPosRand (rrmx, rrmy, rrmz, rminx, rmaxx, rminy, rmaxy, rminz, rmaxz : real)
rpRealModX := rrmx
rpRealModY := rrmy
rpRealModZ := rrmz
rpMinX := rminx
rpMaxX := rmaxx
rpMinY := rminy
rpMaxY := rmaxy
rpMinZ := rminz
rpMaxZ := rmaxz
end InitPosRand
proc InitBaseVect (X, Y, Z : real)
baseXv := X
baseYv := Y
baseZv := Z
end InitBaseVect
proc InitSystem (maxP : int, sx, sy, sz, fx, fy, fz, mas, rad, mLife, Int : real, c : int, pf : boolean)
Default -> Init (sx, sy, sz, fx, fy, fz)
sourceX := sx
sourceY := sy
sourceZ := sz
forceX := fx
forceY := fy
forceZ := fz
maxLife := mLife
maxParticles := maxP
new ParticleSys, maxParticles
for i : 1 .. maxParticles
new ParticleSys (i)
ParticleSys (i) -> LoadSystemVars (Default)
ParticleSys (i) -> Init (
((sourceX + ((Rand.Real * rpRealModX)) * Rand.Int (round (rpMinX), round (rpMaxX)))),
((sourceY + ((Rand.Real * rpRealModY)) * Rand.Int (round (rpMinY), round (rpMaxY)))),
((sourceZ + ((Rand.Real * rpRealModZ)) * Rand.Int (round (rpMinZ), round (rpMaxZ)))),
((baseXv + ((Rand.Real * rvRealModX)) * Rand.Int (round (rvMinX), round (rvMaxX)))),
((baseYv + ((Rand.Real * rvRealModY)) * Rand.Int (round (rvMinY), round (rvMaxY)))),
((baseZv + ((Rand.Real * rvRealModZ)) * Rand.Int (round (rvMinZ), round (rvMaxZ)))),
rad, mas, maxLife - Rand.Int (0, maxLife div LifeC), mLife, Int, c, pf)
end for
end InitSystem
proc Update
for i : 1 .. maxParticles
ParticleSys (i) -> Run
if ParticleSys (i) -> GetLife <= 0 then
ParticleSys (i) -> ReInit (
((sourceX + ((Rand.Real * rpRealModX)) * Rand.Int (round (rpMinX), round (rpMaxX)))),
((sourceY + ((Rand.Real * rpRealModY)) * Rand.Int (round (rpMinY), round (rpMaxY)))),
((sourceZ + ((Rand.Real * rpRealModZ)) * Rand.Int (round (rpMinZ), round (rpMaxZ)))),
((baseXv + ((Rand.Real * rvRealModX)) * Rand.Int (round (rvMinX), round (rvMaxX)))),
((baseYv + ((Rand.Real * rvRealModY)) * Rand.Int (round (rvMinY), round (rvMaxY)))),
((baseZv + ((Rand.Real * rvRealModZ)) * Rand.Int (round (rvMinZ), round (rvMaxZ)))),
maxLife - Rand.Int (0, maxLife div LifeC), maxLife)
end if
end for
end Update
proc DrawSystem
for i : 1 .. maxParticles
ParticleSys (i) -> DrawParticle
end for
end DrawSystem
proc SetReset (X, Y, Z : real)
sourceX := X
sourceY := Y
sourceZ := Z
end SetReset
end ParticleSystem3D |