Special Aircraft Service

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: How best to handle fire textures?  (Read 522 times)

0 Members and 1 Guest are viewing this topic.

WxTech

  • Modder
  • member
  • Offline Offline
  • Posts: 6040
How best to handle fire textures?
« on: July 16, 2024, 12:56:07 AM »

The usual scheme for drawing fire textures is to set tfBlendAdd 1 in the .mat file. This considers the brightness of all elements behind the texture and adding their intensity to that of the texture itself. The result is the propensity for brighter areas to burn out to a very bright and solid hue, potentially all the way to white.

Real fire has a significant opacity; it's not in any way transparent to arbitrary depth. In other words, fire has a small optical depth. And so where the fire has notable volume we are seeing mostly the 'surface'.

In the screenie below the difference between setting tfBlendAdd 1 versus tfBlendAdd 0 is quite considerable. Setting "0", as done for the fire on the right, keeps the fire from going to white or near-white when seen against a lighter background. Indeed, it's a much nearer-to-real appearance of actual fire. The fire on the left has the usual tfBlendAdd 1 setting.

When not adding the blended texture's intensity, the texture requires to have an alpha channel; if not, the black outer part (showing as a square) is seen. This in turn requires to pay attention to the hue of the darker parts of the fire which fade away around the edge of the visible part of the texture, as well has how the alpha channel's own gradients are handled.

This is an experiment to test out the usefulness of making fires more realistic. How this new treatment interacts with smoke particles will be a strong determinant in the utility of the scheme...


Logged
Great minds discuss ideas. Average minds discuss events. Small minds discuss people. - Hyman Rickover (but probably predating his use.)

RABIZO

  • member
  • Offline Offline
  • Posts: 512
Re: How best to handle fire textures?
« Reply #1 on: July 16, 2024, 06:16:17 AM »

I'm looking forward to the new effects.

I like the one on the right better.
Logged

Whiskey_Sierra_972

  • Modder
  • member
  • Offline Offline
  • Posts: 6505
  • In memory of my beloved hero: Saburo SAKAI!
Re: How best to handle fire textures?
« Reply #2 on: July 16, 2024, 07:18:22 AM »

I ageee...no opacity is better for a like real sense!
Logged

vonOben

  • Modder
  • member
  • Offline Offline
  • Posts: 932
  • Wer den Tod fürchtet, hat das Leben verloren.
    • vonOben's Flight Sim Mods
Re: How best to handle fire textures?
« Reply #3 on: July 16, 2024, 12:24:42 PM »

The fire to the right looks much better and more realistic, well done!
 ]thumbsup[
Logged
vonOben's Flight Sim Mods  http://vonoben.free.fr/ Twenty Years online January 3, 2022!

shardana

  • member
  • Offline Offline
  • Posts: 862
Re: How best to handle fire textures?
« Reply #4 on: July 16, 2024, 12:55:22 PM »

Would love to see a video with new fire
Logged

WxTech

  • Modder
  • member
  • Offline Offline
  • Posts: 6040
Re: How best to handle fire textures?
« Reply #5 on: July 17, 2024, 07:00:06 PM »

Here's a short video, showing the appearance of several fires of differing size, in daytime and at night.

Logged
Great minds discuss ideas. Average minds discuss events. Small minds discuss people. - Hyman Rickover (but probably predating his use.)

RABIZO

  • member
  • Offline Offline
  • Posts: 512
Re: How best to handle fire textures?
« Reply #6 on: July 17, 2024, 07:22:07 PM »

Do they also add "black" or "white" smoke on top of the flames?
Logged

WxTech

  • Modder
  • member
  • Offline Offline
  • Posts: 6040
Re: How best to handle fire textures?
« Reply #7 on: July 17, 2024, 09:06:15 PM »

What I've shown here are the FMB fires the player can place in a mission. The smoke column in the background is also an FMB object that I placed with one of the fire objects. These fire and smoke objects can be placed separately or combined, as desired.

For other 'dynamically' generated fire/smoke for destroyed objects, things are largely as to be expected, although I have added some randomness, in part to help with the game engine limitations. For instance, the stock treatment tends to always generate the same fire and smoke for a particular type of object. I've added a chance (generally about 1 in three) for a fire and/or a smoke to NOT be generated. In other words, most times a fire AND smoke are created. But sometimes just the fire OR just the smoke will appear. And sometimes NO fire and NO smoke will be created.

Moreover, I've added a chance for the fire/smoke to be taken from a different object type, which increases variety. For instance, if the static.ini sets the Body type for an object as, say, Rockville, I 1 out of 3 instances the effects for WoodSmall will be used.
Logged
Great minds discuss ideas. Average minds discuss events. Small minds discuss people. - Hyman Rickover (but probably predating his use.)

WxTech

  • Modder
  • member
  • Offline Offline
  • Posts: 6040
Re: How best to handle fire textures?
« Reply #8 on: July 17, 2024, 09:22:41 PM »

Since pointing out the basic scheme in the previous post, let's illustrate the changes in the handling of effects for "House" type objects, which are most of the objects contained in static.ini, I paste here some Java from Explosions.class (I've also made some notable alterations to House.class, but I'll leave that out of this).

First, Here's the stock code in Explosions.HouseExplode(). Note that Body types Wood, Rock and Fuel are handled coarsely.
Code: [Select]
public static void HouseExplode(int i, Loc loc, float af[])
{
if(!Config.isUSE_RENDER())
return;
String s = "";
byte byte0 = 0;
float f = 1.0F;
switch(i)
{
case 0: // '\0'
f = 0.75F;
// fall through

case 1: // '\001'
s = "Wood";
byte0 = 4;
break;

case 2: // '\002'
f = 0.75F;
// fall through

case 3: // '\003'
case 4: // '\004'
s = "Rock";
byte0 = 3;
break;

case 5: // '\005'
f = 0.75F;
// fall through

case 6: // '\006'
s = "Fuel";
byte0 = 5;
break;

default:
System.out.println("WARNING: HouseExplode(): unknown type");
return;
}
String s1 = "effects/Explodes/Objects/House/" + s + "/Boiling.eff";
String s2 = "effects/Explodes/Objects/House/" + s + "/Boiling2.eff";
String s3 = "effects/Explodes/Objects/House/" + s + "/Pieces.eff";
Eff3D.initSetBoundBox(af[0], af[1], af[2], af[3], af[4], af[5]);
Eff3DActor.New(loc, 1.0F, s1, 3F);
Eff3D.initSetBoundBox(af[0] + (af[3] - af[0]) * 0.25F, af[1] + (af[4] - af[1]) * 0.25F, af[2], af[3] - (af[3] - af[0]) * 0.25F, af[4] - (af[4] - af[1]) * 0.25F, af[2] + (af[5] - af[2]) * 0.5F);
Eff3DActor.New(loc, 1.0F, s3, 3F);
if(i != 0)
{
String s4 = "effects/Explodes/Objects/House/" + s + "/Fire_Smoke.eff";
RangeRandom rangerandom = World.rndPos(loc.getX(), loc.getY());
float f1 = rangerandom.nextFloat();
if((double)f1 > 0.5D)
{
float f2 = rangerandom.nextFloat(300F, 600F);
Eff3DActor.New(loc, f, s4, f2);
Eff3DActor.New(loc, f, s2, f2);
} else
{
Eff3DActor.New(loc, f, s4, 5F);
Eff3DActor.New(loc, f, s2, 5F);
}
} else
{
Eff3DActor.New(loc, f, s2, 3F);
}
SfxExplosion.building(loc.getPoint(), byte0, af);
}



Here's my expanded Explosions.HouseExplode(). I handle all Body types in a more granular way, and add consideration of the new types Flesh and Vehicle.
Code: [Select]
public static void HouseExplode(int i, Loc loc, float fs[])
//called in House.class; i = prop.EXPL_TYPE (was 0 to 6, then 0 to 7, now 0 to 8)
{
if(!Config.isUSE_RENDER())
return;
Point3d point3d = new Point3d();
Point3d point3d1 = loc.getPoint();  //New by WxTech
o.set(0.0F, 90.0F, 0.0F);  //New by WxTech
l.set(point3d1, o);  //New by WxTech
String string = "";
boolean bFuel = false;  //becomes true if "FuelSmall" or "Fuel", i.e., the fuel type
boolean bBig = false;  //becomes true if "WoodMiddle", "RockHuge" or "FuelBig", i.e., the largest sizes of all types; did include "RockBig", but feel it might be best left out...
scaleFire = MiscEffects.cvt(World.Sun().ToSun.z, -0.25F, 0.0F, 2.0F, 1.0F);  //for other than Fuel
scaleFireFuel = MiscEffects.cvt(World.Sun().ToSun.z, -0.25F, 0.0F, 1.7F, 1.0F);  //for FuelBig and FuelSmall; Not as aggressive
float scaleLight = MiscEffects.cvt(World.Sun().ToSun.z, -0.25F, 0.0F, 1.0F, 0.5F);

fSmokeFireTimeFactor_1 = Config.cur.ini.get("Mods", "SmokeFireTimeFactor_Building", 4F);  //Apr 3, 2024; allow player to set a factor for duration of long-lasting smoke/fire
if(fSmokeFireTimeFactor_1 < 1F)
fSmokeFireTimeFactor_1 = 1F;
if(fSmokeFireTimeFactor_1 > 100F)
fSmokeFireTimeFactor_1 = 100F;

//HUD.training("SFLTF_1: " + fSmokeFireLiveTimeFactor_1);

byte byte0;  //related to explosion sound (SfxExplosion.building); 3=Rock, 4=Wood, 5=Metall
int i_alt_;  //Body type value, original and alternate assignment
switch (i)
// Allowed body types are: WoodSmall, WoodMiddle, RockMiddle, RockBig, RockHuge, FuelSmall, FuelBig, Flesh, Vehicle
{
case 0: //WOOD_SMALL (and FLESH, originally)
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "Flesh";  //is smaller
i_alt_ = 7;
}
else
{
string = "WoodSmall";
i_alt_ = 0;
}
byte0 = 4;
break;
case 1: //WOOD_MIDDLE
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "WoodSmall";  //is smaller
i_alt_ = 0;
}
else
{
string = "Wood";
i_alt_ = 1;
bBig = true;
}
byte0 = 4;
break;
case 2: //ROCK_MIDDLE
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "WoodSmall";  //is similar size
i_alt_ = 0;
}
else
{
string = "RockMiddle";
i_alt_ = 2;
}
byte0 = 3;
break;
case 3: //ROCK_BIG
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "Wood";  //is about similar size
i_alt_ = 1;
}
else
{
string = "RockBig";
i_alt_ = 3;
// bBig = true;  //may not want to keep this
}
byte0 = 3;
break;
case 4: //ROCK_HUGE
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "Wood";  //is smaller
i_alt_ = 1;
}
else
{
string = "Rock";
i_alt_ = 4;
bBig = true;
}
byte0 = 3;
break;
case 5: //FUEL_SMALL
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "Vehicle";  //is smaller
i_alt_ = 8;
}
else
{
string = "FuelSmall";
i_alt_ = 5;
bFuel = true;
}
byte0 = 5;
break;
case 6: //FUEL_BIG
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "FuelSmall";
i_alt_ = 5;
bFuel = true;  //is fuel
}
else
{
string = "Fuel";
i_alt_ = 6;
bFuel = true;  //is fuel
bBig = true;
}
byte0 = 5;
break;
case 7: //FLESH  -- NEW!!!
if (TrueRandom.nextFloat() < 0.66F)  //2/3 will not generate effects
return;
string = "Flesh";
i_alt_ = 7;
byte0 = 4;
break;
case 8: //VEHICLE  -- NEW!!!
if (TrueRandom.nextFloat() < 0.33F)  //1/3 will not generate effects
return;
if (TrueRandom.nextFloat() < 0.33F)
{
string = "Flesh";
i_alt_ = 7;
}
else
{
string = "Vehicle";
i_alt_ = 8;
}
byte0 = 5;
break;
default:
System.out.println("WARNING: HouseExplode(): unknown type");
return;
}
Eff3D.initSetBoundBox(fs[0], fs[1], fs[2], fs[3], fs[4], fs[5]);  //X, Y, Z, X', Y', Z'
Eff3D.initSetBoundBox(fs[0] + (fs[3] - fs[0]) * 0.25F, fs[1] + (fs[4] - fs[1]) * 0.25F, fs[2], fs[3] - (fs[3] - fs[0]) * 0.25F, fs[4] - (fs[4] - fs[1]) * 0.25F, fs[2] + (fs[5] - fs[2]) * 0.5F);  //STOCK! makes half size; -X, -Y, -Z as is, X, Y, Z midpoint
float Volume = Math.abs(fs[0] - fs[3]) * Math.abs(fs[1] - fs[4]) * Math.abs(fs[5] - fs[2]);  //volume of mesh, in m^3
Eff3DActor.New(l, 1.0F, "Effects/Explodes/_Empty.eff", -1F);  //NEW! this first effect gets re-scaled by the annoying BoundBox behaviour, hence making this a 'throw-away' effect
// if (Math.abs(fs[0] - fs[3]) > 20 || Math.abs(fs[1] - fs[4]) > 20 || Math.abs(fs[5] - fs[2]) > 20)  //for buildings > 20m across or tall
// if (Volume > 4000F && i > 0 && i < 5)  //4000m^3 is, e.g., 20 * 20 * 10, or 15.9m cubed; also only if WoodMiddle or any of the three Rock Body types
if (Volume > 4000F && i < 5 && TrueRandom.nextFloat() < 0.5F)  //4000m^3 is, e.g., 20 * 20 * 10, or 15.9m cubed; for all Wood and Rock types (not for Fuel, Flesh or Vehicle)
{
// float tim = TrueRandom.nextFloat(660F, 900F);  //11-15min
float tim = TrueRandom.nextFloat(50.0F, 80.0F);
float f_0_ = tim * fSmokeFireTimeFactor_1;
Eff3DActor.New(l, 1.0F, "Effects/Explodes/Objects/Building20m/Structure.eff", -1F);  //chunks, always thrown
if(tim > 65F)  //midway between 50 and 80; was 780=13min; midway between 660 and 900
Eff3DActor.New(l, 1.0F, "Effects/Explodes/Objects/Building20m/Smoke.eff", f_0_);  //persistent lighter smoke when f_0_ longer, 13-15min
else
Eff3DActor.New(l, 1.0F, "Effects/Explodes/Objects/Building20m/Smoke2.eff", f_0_);  //persistent darker smoke when f_0_ shorter, 11-13min
Eff3DActor eff3dactor = Eff3DActor.New(l, scaleFireFuel, "Effects/Explodes/Objects/Building20m/Fire.eff", TrueRandom.nextFloat(0.85F, 0.95F) * f_0_);  //persistent fire, 15m
if (World.Sun().ToSun.z < 0.0F)  //100% chance of light source
{
LightPointActor lightpointactor = new LightPointActor(new LightPointWorld(), new Point3d(0.0D, 0.0D, 10.0D));
lightpointactor.light.setColor(1.0F, 0.6F, 0.2F);
lightpointactor.light.setEmit(1.0F * scaleLight, 250F * scaleLight);  //was 1, 200
eff3dactor.draw.lightMap().put("light", lightpointactor);
}
}else  //other than big building WITH big effects above
{
String string_1_ = "Effects/Explodes/Objects/House/" + string + "/Pieces.eff"; //exploded bits (fireballs for Fuel) [was Boiling]
String string_2_ = "Effects/Explodes/Objects/House/" + string + "/BlastCloud.eff"; //ground-level blast smoke/dust [was Pieces]
String string_3_ = "Effects/Explodes/Objects/House/" + string + "/Fire.eff"; //long-lasting fire [was Boiling2]
String string_4_ = "Effects/Explodes/Objects/House/" + string + "/Smoke.eff"; //main long-lasting smoke [was Fire_Smoke]
String string_4A_ = "Effects/Explodes/Objects/House/" + string + "/Smoke_alternate.eff"; //ALTERNATE Fire_Smoke, 50% chance; denser/darker; NONE for fuel [was Fire_Smoke2]
String string_5_ = "Effects/Explodes/Objects/House/" + string + "/Smoke_billowing.eff"; //NEW!!! billowing smoke texel for FUEL_BIG only [name unchanged]
Eff3DActor.New(l, 1.0F, string_2_, -1F);     //ground-level blast smoke/dust; keep unity scale for all
if (i_alt_ > 0 && i_alt_ < 7)  //if i_alt_ 1 to 6, i.e., NOT WoodSmall, Flesh, Vehicle --  NEW!!!!!!!
{
if (bBig)  //if of the larger sizes, create larger fire/smoke
{
// float f_1_ = TrueRandom.nextFloat(450.0F, 600.0F);  //originally 300 to 600 sec duration (5 to 10 min)
float f_1_ = TrueRandom.nextFloat(40.0F, 60.0F) * fSmokeFireTimeFactor_1;  //live time
if (TrueRandom.nextFloat() < 0.5F && i < 5)  //May 23, 2024; to randomly select alternate smoke (denser/darker) for Wood and Rock--not fuel
Eff3DActor.New(l, 1.0F, string_4A_, f_1_); //alternate smoke
else
Eff3DActor.New(l, 1.0F, string_4_, f_1_); //smoke, 450-600 sec
if (bFuel)  //if "Fuel" (big, in this case)
{
if(TrueRandom.nextFloat() < 0.2F)
Fuel_Fireball_Big(point3d1);  //very prominent fireball merging into smoke
else
Eff3DActor.New(l, 1.0F, string_1_, -1F);  //fireballs
Eff3DActor.New(l, 1.0F, string_5_, f_1_ * 0.9F); //Smoke_billowing, lasts as long as does the full-duration fire
Eff3DActor eff3dactor = Eff3DActor.New(l, scaleFireFuel, string_3_, f_1_ * 0.9F);  //fire; 450-600 sec * 0.9
if (World.Sun().ToSun.z < 0.0F)  //100% chance of light source
{
LightPointActor lightpointactor = new LightPointActor(new LightPointWorld(), new Point3d());
lightpointactor.light.setColor(1.0F, 0.6F, 0.2F);
lightpointactor.light.setEmit(1.0F * scaleLight, 200F * scaleLight);  //was 1, 150
eff3dactor.draw.lightMap().put("light", lightpointactor);
}
}else  //if not "Fuel"
{
if (TrueRandom.nextFloat() < 0.7F)
{
Eff3DActor.New(l, 1.0F, string_1_, -1F);  //exploded bits
Eff3DActor eff3dactor = Eff3DActor.New(l, scaleFire, string_3_, f_1_ * 0.85F);  //fire
if (World.Sun().ToSun.z < 0.0F && TrueRandom.nextFloat() < 0.1F)  //NEW! Had at 20%; 10% chance of light source for larger objects
{
LightPointActor lightpointactor = new LightPointActor(new LightPointWorld(), new Point3d());
lightpointactor.light.setColor(1.0F, 0.6F, 0.2F);
lightpointactor.light.setEmit(1.0F * scaleLight, 175F * scaleLight);
eff3dactor.draw.lightMap().put("light", lightpointactor);
}
}
}
} else  //if of the small size (NOT bBig)
{
// float f_2_ = TrueRandom.nextFloat(280.0F, 450.0F);  //originally 100 to 200 sec duration
float f_2_ = TrueRandom.nextFloat(25.0F, 45.0F) * fSmokeFireTimeFactor_1;
if (TrueRandom.nextFloat() < 0.5F && i < 5)  //May 23, 2024; to randomly select alternate smoke (denser/darker) for Wood and Rock--not fuel
Eff3DActor.New(l, 1.0F, string_4A_, f_2_); //alternate smoke
else
Eff3DActor.New(l, 1.0F, string_4_, f_2_); //smoke, was 5 sec
if (bFuel)  //if "Fuel" (small, in this case)
{
if(TrueRandom.nextFloat() < 0.2F)
Fuel_Fireball(point3d1);  //prominent fireball merging into smoke
else
Eff3DActor.New(l, 1.0F, string_1_, -1F);  //fireballs
Eff3DActor.New(l, 0.9F, "Effects/Smokes/SmokeOilTank4.eff", f_2_ * 0.9F);  //NEW effect; animated billowing smoke (for train oil wagons); 280-450 sec * 0.9; NOTE SCALE FACTOR
Eff3DActor eff3dactor = Eff3DActor.New(l, scaleFireFuel, string_3_, f_2_ * 0.9F);  //fire; 280-450 sec * 0.9
if (World.Sun().ToSun.z < 0.0F && TrueRandom.nextFloat() < 0.3F)  //30% chance of light source
{
LightPointActor lightpointactor = new LightPointActor(new LightPointWorld(), new Point3d());
lightpointactor.light.setColor(1.0F, 0.6F, 0.2F);
lightpointactor.light.setEmit(1.0F * scaleLight, 100F * scaleLight);
eff3dactor.draw.lightMap().put("light", lightpointactor);
}
}else  //if not "Fuel"
{
if (TrueRandom.nextFloat() < 0.7F)
Eff3DActor.New(l, scaleFire, string_3_, f_2_ * 0.85F);  //fire; 70% chance
Eff3DActor.New(l, 1.0F, string_1_, -1F);  //exploded bits; always
}
}
} else  //if i_alt_ = 0, 7, or 8 (WoodSmall, Flesh, Vehicle)
if (i_alt_ == 0 || i_alt_ == 7 || i_alt_ == 8)
{
// float f_3_ = TrueRandom.nextFloat(180.0F, 360.0F);  //3 - 6 min; originally 30 to 60 sec duration
float f_3_ = TrueRandom.nextFloat(20.0F, 40.0F) * fSmokeFireTimeFactor_1;  //live time
if (i_alt_ == 7)  //if Flesh (NO FIRE)
{
f_3_ *= 0.33F;   //make live time last 1/3 as long, or 1.5 - 3 min
if (TrueRandom.nextFloat() < 0.33F)  //make smoke effect occur in 1/3 of instances (in addition to the already 1/3 probability)
{
if (TrueRandom.nextFloat() < 0.5F)  //May 23, 2024; to randomly select alternate smoke (denser/darker)
Eff3DActor.New(l, 1.0F, string_4A_, f_3_); //alternate smoke
else
Eff3DActor.New(l, 1.0F, string_4_, f_3_); //smoke ONLY, no fire
}
} else  //if i_alt_ = 0 or 8 (WoodSmall, Vehicle)
{
if (TrueRandom.nextFloat() < 0.7F)
{
if (TrueRandom.nextFloat() < 0.5F)  //May 23, 2024; to randomly select alternate smoke (denser/darker)
Eff3DActor.New(l, 1.0F, string_4A_, f_3_); //alternate smoke
else
Eff3DActor.New(l, 1.0F, string_4_, f_3_); //smoke
if (TrueRandom.nextFloat() < 0.7F)
Eff3DActor.New(l, scaleFire, string_3_, f_3_ * 0.85F);  //fire; 50% net chance; 180-360 sec * 0.85
}
Eff3DActor.New(l, 1.0F, string_1_, -1F);  //Boiling; exploded bits, always
}
}
}
SfxExplosion.building(loc.getPoint(), byte0, fs);
}



I've added a NEW secondary explosion effect, implemented randomly for suitable objects by the new method Explosions.HouseSecondaryExplode():
Code: [Select]
public static void HouseSecondaryExplode(float f, Loc loc)
//NEW! called from House.runDeathShow(); f = prop.SECONDARY_EXPL (1=big blast, 2=big fireball, 3=hybrid big blast/fireball, 4=small fireball)
{
if (f < 0.5F)  //valid values are 1, 2, 3 or 4
return;
if(!Config.isUSE_RENDER())
return;
Point3d point3d = new Point3d();
Point3d point3d1 = loc.getPoint();
o.set(0.0F, 90.0F, 0.0F);
l.set(point3d1, o);
if (((f > 0.5F && f < 1.5F) || (f > 2.5F && f < 3.5F)) && TrueRandom.nextFloat() < 0.25F)  //if f = 1 for blast or 3 for hybrid; had prob 0.15
{
final Loc loc_1 = new Loc(point3d1);
double tim = TrueRandom.nextDouble(10.0, 20.0);  //was 10, 20
new MsgAction(tim)
{
public void doAction(Object obj)
{
Point3d point3d2 = new Point3d();
point3d2 = loc_1.getPoint();
SecondaryExpl(point3d2);  //sound is part of method
}
};
if (f > 2.5F && f < 3.5F && TrueRandom.nextFloat() < 0.5F)  //add chance of fireball if "3"; make prob about 0.5
{
new MsgAction(tim + TrueRandom.nextDouble(5.0, 8.0))  //delays fireball by 5-8s after start of blast
{
public void doAction(Object obj)
{
Point3d point3d2 = new Point3d();
point3d2 = loc_1.getPoint();
Fuel_Fireball_Big(point3d2);  //sound is part of method
}
};
}
}
if (f > 1.5F && f < 2.5F && TrueRandom.nextFloat() < 0.2F)  //if f = 2, for fireball alone; had prob 0.15
{
final Loc loc_1 = new Loc(point3d1);
new MsgAction(TrueRandom.nextDouble(10.0, 20.0))  //was 10, 20
{
public void doAction(Object obj)
{
Point3d point3d2 = new Point3d();
point3d2 = loc_1.getPoint();
Fuel_Fireball_Big(point3d2);  //sound is part of method
}
};
}
if (f > 3.5F && f < 4.5F && TrueRandom.nextFloat() < 0.15F)  //if f = 4, for small fireball alone (good for, e.g., fuel barrels)
{
final Loc loc_1 = new Loc(point3d1);
new MsgAction(TrueRandom.nextDouble(7.0, 14.0))  //was 7, 14
{
public void doAction(Object obj)
{
Point3d point3d2 = new Point3d();
point3d2 = loc_1.getPoint();
Fuel_Fireball(point3d2);  //sound is part of method
}
};
}
}



And to generate the secondary explosions themselves, with ballistic particles of firey smoke trails, this NEW method, Explosions.SecondaryExpl() was written:
Code: [Select]
public static void SecondaryExpl(Point3d point3d)
//NEW! for static objects, like buildings, etc.; patterned after ExplodeAmmo; do not tie to explosive damage--too potentially dangerous for wild chain reactions.
{
if(!Config.isUSE_RENDER())
return;
Loc loc = new Loc(point3d);
o.set(0.0F, 90.0F, 0.0F);
loc.set(point3d, o);
float f1 = TrueRandom.nextFloat(1.0F, 1.5F);  //range of flash/ammovag fireball size, native 40m expanding to 100m diam. (now up to 60-150)
Eff3DActor.New(loc, f1, "Effects/Explodes/Objects/ExplodeAmmo/Smoke.eff", -1F);
Eff3DActor.New(loc, f1, "Effects/Explodes/Objects/ExplodeAmmo/Ammovag_expl.eff", -1F);  //slower fireball
Eff3DActor.New(loc, 1.0F, "Effects/Explodes/Objects/ExplodeAmmo/Shock.eff", -1F);
Eff3DActor.New(loc, 1.0F, "Effects/Explodes/Objects/ExplodeAmmo/Sparks.eff", -1F);
Eff3DActor.New(loc, 1.0F, "Effects/Explodes/Objects/ExplodeAmmo/Pieces.eff", -1F);
Eff3DActor eff3dactor = Eff3DActor.New(loc, f1, "Effects/Explodes/Objects/ExplodeAmmo/Burn.eff", -1F);  //rapid flash, live time 0.6s
if (World.Sun().ToSun.z < 0.0F)
{
float scaleLight = MiscEffects.cvt(World.Sun().ToSun.z, -0.25F, 0.0F, 1.0F, 0.5F);
LightPointActor lightpointactor = new LightPointActor(new LightPointWorld(), new Point3d());
lightpointactor.light.setColor(1.0F, 0.6F, 0.2F);
lightpointactor.light.setEmit(1.0F * scaleLight, 250F * f1 * scaleLight);
eff3dactor.draw.lightMap().put("light", lightpointactor);
}
Vector3d vector3d = new Vector3d();
int j = TrueRandom.nextInt(4, 8);  //4 to 7 each FAST and SLOW ballistic particles
for (int j_1_ = 0; j_1_ < j; j_1_++)
{
vector3d.set((double) TrueRandom.nextFloat(-1.0F, 1.0F), (double) TrueRandom.nextFloat(-1.0F, 1.0F), (double) TrueRandom.nextFloat(0.5F, 1.0F));  //had Z as (0.6, 1)
vector3d.normalize();
vector3d.scale((double) TrueRandom.nextFloat(120.0F, 240.0F));  //speed scale factor, to get m/s; had 180, 240
float f = TrueRandom.nextFloat(0.5F, 0.625F);  //range of live time in seconds; was 0.4, 0.5
BallisticProjectile ballisticprojectile = new BallisticProjectile(loc.getPoint(), vector3d, f);
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "Effects/Explodes/Objects/ExplodeAmmo/SmokeTendril.eff", f);


vector3d.set((double) TrueRandom.nextFloat(-1.0F, 1.0F), (double) TrueRandom.nextFloat(-1.0F, 1.0F), (double) TrueRandom.nextFloat(0.5F, 1.0F));
vector3d.normalize();
vector3d.scale((double) TrueRandom.nextFloat(20.0F, 60.0F));  //speed scale factor, to get m/s; was 30, 50
float f_1_ = TrueRandom.nextFloat(9F, 14F);  //range of live time in seconds; was 9, 13
ballisticprojectile = new BallisticProjectile(loc.getPoint(), vector3d, f_1_);
if (TrueRandom.nextFloat() < 0.5F)
{
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "3DO/Effects/Aircraft/EngineSmokeMediumSPD.eff", f_1_);
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "3DO/Effects/Aircraft/EngineSmokeMediumTSPD.eff", f_1_);
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "Effects/Explodes/Wreckage_Burn_2.eff", f_1_);
} else
{
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "Effects/Explodes/Wreckage_Burn_2.eff", f_1_ * 1.5F);  //NEW effect
Eff3DActor.New(ballisticprojectile, null, null, 1.0F, "Effects/Explodes/Wreckage_Smoke_2.eff", f_1_ * 1.5F);  //NEW effect, thinner smoke trail
}
}
// SfxExplosion.crashAir(point3d, 0);  //0=sound on land, 1=sound in air, 2=sound on water
SfxExplosion.shell(point3d, 0, 300, 0, 300);  //(air/water/land, power (50 is transition betwen "middle" and "big"), powerType (0 = no splinters), range)
o.set(0.0F, 0.0F, 0.0F);
l.set(point3d, o);
ExplodeSurfaceWave(0, 208F, 0.4F);  //texture expansion 520m/s

if (point3d.z - Engine.land().HQ_Air(point3d.x, point3d.y) < 36.0)  //from Bomb250 Object
{
if (Engine.land().isWater(point3d.x, point3d.y))  //add 24 to 35 small water shrapnel hits randomly placed around explosion
shrapnelSplashWater(point3d, 27, 41, 40F, 0.8F, 0.25F, 5F, 3F);  //was 7, 3
else
if (!Engine.land().isWater(point3d.x, point3d.y))  //superfluous?
shrapnelSplashLand(point3d, 27, 41, 40F, 0.8F);
}
}
Logged
Great minds discuss ideas. Average minds discuss events. Small minds discuss people. - Hyman Rickover (but probably predating his use.)

Geschirr

  • member
  • Offline Offline
  • Posts: 834
  • "A plan is a list of things that won't happen."
Re: How best to handle fire textures?
« Reply #9 on: July 17, 2024, 09:38:48 PM »

Wow they look sooooooooo much better!  Good job!!!
Logged
"If we don't know what we're doing, neither will the enemy."

RABIZO

  • member
  • Offline Offline
  • Posts: 512
Re: How best to handle fire textures?
« Reply #10 on: July 17, 2024, 09:59:54 PM »

I didn't know it could be placed with "FMB".
I can expect some "good effects" from combining them.
Now there's more to look forward to.

I can't wait.
Logged

raf1659

  • member
  • Offline Offline
  • Posts: 369
Re: How best to handle fire textures?
« Reply #11 on: July 18, 2024, 12:42:28 AM »

Bravo !  ]cheers[
Logged
Pages: [1]   Go Up
 

Page created in 0.042 seconds with 26 queries.