OBD talk:BINA/PAR3: Difference between revisions

From OniGalore
Jump to navigation Jump to search
m (content of "particle_sprite_type.wmm_" = sprite mode numbers?)
No edit summary
Line 172: Line 172:


Are these the numbers for the sprite mode mask? [[User:Ssg|Ssg]] 21:51, 5 February 2008 (CET)
Are these the numbers for the sprite mode mask? [[User:Ssg|Ssg]] 21:51, 5 February 2008 (CET)
I'll check the code to make sure but it looks like you hit the nail on the head. Thanks!
[[User:Neo|Neo]]

Revision as of 21:02, 5 February 2008

To value types:

What the both values of the normal distribution stand for?

First value μ (mean) and second value σ (standard deviation)?

Ssg 23:13, 5 December 2007 (CET)

No as far as I can tell. The value is interpolated from an "InverseNormalTable" (0, 0.125, 0.2533, 0.3850, 0.5244, 0.6745, 0.8416, 1.0364, 1.2816, 1.6449, 3.0902, 1.6449, 1.2816, ...). The resulting value is multiplied with the second value and the first value is added to the result, so those 2 value are more like "offset" and "scale". I don't know why the table is called "InverseNormal", maybe this is actually normal inverse distribution but it does not look like so.

Neo

Thanks for your answer.

I've googled a (long) bit for that "InverseNormalTable". It seems to be okay. This table is also called "inverse standardized normal distribution" (see http://files.hanser.de/hanser/docs/20040419_24419112747-75_3-446-21594-8Anhang2.pdf)

The equation for the inverse normal distribution is: x = σ * z + μ

with:

x = result
z = looked up in the z-table (the z-table here is the InverseNormalTable)
μ = mean
σ = standard deviation

Unfortunately I've no idea what's the basis for Oni's interpolation (IMO Oni needs an entry point for the table), so I haven't got a clue what the result is for.

Ssg 20:26, 6 December 2007 (CET)

The interpolation is easy: it picks a random number between -9.99 and 9.99 and it uses it to interpolate the table (linear interpolation).

And I don't know if you noticed, the WMDD for values says "Bell Curve" :)

Neo

A quick note: I messed up the table, it's (-3.0902, ..., -0.2533, -0.125, 0, 0.125, 0.2533, 0.3850, 0.5244, 0.6745, 0.8416, 1.0364, 1.2816, 1.6449, 3.0902).

Neo

>>it picks a random number between -9.99 and 9.99 and it uses it to interpolate the table (linear interpolation).

I don't get that. Can you give an example, please? Let's say Oni picks up the value 9. How does the interpolation work?

Like this:

-3.0902 = -9.99
-1.6449 = -8.99
...
-0.125 = -0.99
0 = 0
...
3.0902 = 9.99?

>>And I don't know if you noticed, the WMDD for values says "Bell Curve" :)

Yes, I've noticed that. Do you think the first value is not the mean?

>>I messed up the table

No problem. Now it fits much better to the pdf file above. ;-)

Ssg 22:32, 6 December 2007 (CET)

This should clear up everything:

float InverseNormalTable[] = { 0.0f, 0.125f, 0.2533f, 0.3853f, 0.5244f, 0.6745f, 0.8416f, 1.0364f, 1.2816f, 1.6449f, 3.0902f };

float InverseNormalRandom(float v1, float v2)
{
    float r = frnd(); // generates a random number in [-0.999, 0.999]
    float x = fabsf(r) * 10.0f;
    int i = floorf(x);
    float z = InverseNormalTable[i] + (x - i) * (InverseNormalTable[i + 1] - InverseNormalTable[i]);

    if (r < 0.0f)
        z = -z;

    return v1 + z * v2;
}

Neo

The term "inverse normal" is apparently not conventional, and also rather confusing because it can be mistaken as referring to either the normal-inverse Gaussian distribution or the inverse Gaussian distribution, both of which are rather exotic and irrelevant here.
What we have here is the inverse of the error function or rather that of erfc(x/sqrt(2)). If you have Java installed, HERE is a nice applet that you can toy around with to see just what the table in your PDF link corresponds to.
As further pointed out HERE, inverting the standard normal cdf gives you a way to generate normally distributed random variables from a uniformly distributed random variable, which is exactly what Oni does (see Neo's code sample above).
The float r is a uniformly distributed random variable in (-1.0,1.0) (@ Neo: please check). Same for x except the interval is now [0.0,10.0). z is a first approximation of erfc(0.0998 * x / sqrt(2)), interpolated linearly between erfc(0.0998 * floorf(x) / sqrt(2)) and erfc(0.0998 * (floorf(x) + 1) / sqrt(2)). The table is thus sampled uniformly.
The result ( v1 + z * v2 ) is, to a good approximation, a normally distributed random variable, centered at v1 and with standard mean deviation v2. Apart from the approximation arising from the linear interpolation, the distribution is cut off at 99.8% of expectancy, so all the values will be within 3.09023*v2 of v1.
geyser 03:12, 7 December 2007 (CET)

Boy, what a ton of interest this little function generates :). The interval for r is [-0.999, 0.999] to be precise (it originates as [-1, 1] and it is multiplied with 0.999). And yes, it is supposed to be distributed uniformly. Here is the (pseudo)random number generator: linear congruential generator, the one from Numerical Recipes.


Neo

>>HERE is a nice applet

Oh, that's why I couldn't see anything when I found this site. It needs Java.

>>gives you a way to generate normally distributed random variables from a uniformly distributed random variable, which is exactly what Oni does

Ahhhhhh... that's the thought behind that calculation.

Ssg 12:20, 7 December 2007 (CET)

@ Neo & WIMC: "The interval for r is [-0.999, 0.999]"
That's odd because then the interval for x is [0, 9.99],
meaning that they leave out 0.1% of the inverse table
(i.e., they will sample only 99% of the last interval)
The only reason why they'd do this is to avoid i=10...
Anyway, this affects the final distribution very little.
Instead of a cutoff at 98% they have 97.902%: big deal.
geyser 18:04, 7 December 2007 (CET)

>> The only reason why they'd do this is to avoid i=10...

Most likely, they'd need a special case for that and it just doesn't worth it. And guys, let's just stop here. Remember, it is a game and not a scientific program, they might have as well drawn an upside down bell on a napkin, digitize it and put the obtained values in that table and it would still work :).
Neo

notepad

variables

  • storage types: would read it like that
01 00 00 00 - int16
02 00 00 00 - float
04 00 00 00 - string? (16 bytes)
08 00 00 00 - colour (4 bytes)
10 00 00 00 - int32
20 00 00 00 - string? (16 bytes)
40 00 00 00 - string? (16 bytes)
00 00 00 00 - pingpong state
00 10 00 00 - action index
00 20 00 00 - emitter
00 30 00 00 - blast falloff
00 40 00 00 - coord frame
00 50 00 00 - collision orient
00 60 00 00 - boolean
00 70 00 00 - ambient sound
00 80 00 00 - impulse sound
00 90 00 00 - impact modifier
00 A0 00 00 - damage type
00 B0 00 00 - axis

emitted particles

  • 0x68 - why is there a ? behind "can use element 12"

Ssg 00:58, 25 December 2007 (CET)

  • Well, you can read it like that if you want but I'm not sure why does it matter, they're just a bunch of values that identify some types. What you suggest looks more like flags/bitsets but they are not. (Besides don't expect me or any other C/C++ programmer to support such a format for flags/bitset because no one ever treats a 32 bit flags field as 4 separate bytes.)
  • Because I managed to check the usage of all other fields in the executable except these 2 fields (11 & 12).

Neo


There's a "particle_sprite_type.wmm_" that says:

0 - sprite (face camera orient to screen)
1 - rotated sprite (face camera orient to particle)
/ - none
2 - beam (parallel face camera)
3 - arrow (parallel orient to particle)
7 - discus (parallel orient to particle)
/ - none
4 - flat (perpendicular)
/ - none
5 - contrail (orient to particle)
6 - contrail (face camera)

Are these the numbers for the sprite mode mask? Ssg 21:51, 5 February 2008 (CET)

I'll check the code to make sure but it looks like you hit the nail on the head. Thanks!

Neo