From: Samual Date: Thu, 24 May 2012 16:09:09 +0000 (-0400) Subject: Merge remote-tracking branch 'origin/master' into samual/spawn_weapons X-Git-Tag: xonotic-v0.8.0~152^2~408^2~80 X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=cfdec7de4f6fff90a2142be820eaeb43a5f7f572 Merge remote-tracking branch 'origin/master' into samual/spawn_weapons Conflicts: effectinfo.txt qcsrc/common/util.qc qcsrc/common/util.qh --- cfdec7de4f6fff90a2142be820eaeb43a5f7f572 diff --cc effectinfo.txt index 2213c126de,5e06d075e6..38a14489d0 --- a/effectinfo.txt +++ b/effectinfo.txt @@@ -7410,83 -7410,3 +7410,83 @@@ velocityjitter 64 64 6 //lightradiusfade 50 //lightcolor 1 0.9 0.7 //lightshadow 1 + +// laser_shockwave_attack +// used nowhere in code +effect laser_shockwave_attack +// glow and light +//countabsolute 1 +//type smoke +//color 0xcc0000 0xff0000 +//tex 65 65 +//size 10 15 +//alpha 256 512 6280 +//airfriction 10 +//sizeincrease 1.5 +//stretchfactor 2 +//lightradius 200 +//lightradiusfade 2000 +//lightcolor 3 0.1 0.1 +// electricity +effect laser_shockwave_attack +count 1 +type spark +color 0xb44215 0xff0000 +tex 43 43 +size 5 7 +bounce 0 +alpha 4096 4096 20000 +airfriction 1 +originjitter 2 2 2 +velocityjitter 10 10 10 +velocitymultiplier 10 +sizeincrease 1.5 +stretchfactor 2.3 +rotate -180 180 4000 -4000 +// fire +effect laser_shockwave_attack +count 1 +type spark +color 0xff4200 0xff0000 +tex 8 15 +size 7 9 +bounce 0 +alpha 4096 4096 20000 +airfriction 1 +originjitter 2 2 2 +velocityjitter 10 10 10 +velocitymultiplier 10 +sizeincrease 1.5 +stretchfactor 2 + +// new_laser_impact +// used nowhere in code +// decal +effect new_laser_impact +countabsolute 1 +type decal +tex 8 16 +size 72 72 +alpha 256 256 0 +originjitter 2 2 2 +// flare effect +//effect new_laser_impact +//countabsolute 1 +//type static +//tex 39 39 +//color 0xFF2010 0xFF2010 +//alpha 256 256 1024 +//size 24 24 +// sparks that rapidly expand and rapidly slow down to form an interesting spherical effect +effect new_laser_impact +count 128 +type spark +color 0x800000 0xFF8020 +alpha 256 256 1024 +size 4 4 +bounce 1.5 +gravity 0.5 +airfriction 1 +liquidfriction 1 +originjitter 20 20 20 - velocityjitter 256 256 256 ++velocityjitter 256 256 256 diff --cc qcsrc/common/util.qc index da78733c71,6e534ffc19..f99312b5b2 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@@ -2370,194 -2365,54 +2370,246 @@@ void queue_to_execute_next_frame(strin to_execute_next_frame = strzone(s); } + float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x) + { + return + ((( startspeedfactor + endspeedfactor - 2 + ) * x - 2 * startspeedfactor - endspeedfactor + 3 + ) * x + startspeedfactor + ) * x; + } + + float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor) + { + if(startspeedfactor < 0 || endspeedfactor < 0) + return FALSE; + + /* + // if this is the case, the possible zeros of the first derivative are outside + // 0..1 + We can calculate this condition as condition + if(se <= 3) + return TRUE; + */ + + // better, see below: + if(startspeedfactor <= 3 && endspeedfactor <= 3) + return TRUE; + + // if this is the case, the first derivative has no zeros at all + float se = startspeedfactor + endspeedfactor; + float s_e = startspeedfactor - endspeedfactor; + if(3 * (se - 4) * (se - 4) + s_e * s_e <= 12) // an ellipse + return TRUE; + + // Now let s <= 3, s <= 3, s+e >= 3 (triangle) then we get se <= 6 (top right corner). + // we also get s_e <= 6 - se + // 3 * (se - 4)^2 + (6 - se)^2 + // is quadratic, has value 12 at 3 and 6, and value < 12 in between. + // Therefore, above "better" check works! + + return FALSE; + + // known good cases: + // (0, [0..3]) + // (0.5, [0..3.8]) + // (1, [0..4]) + // (1.5, [0..3.9]) + // (2, [0..3.7]) + // (2.5, [0..3.4]) + // (3, [0..3]) + // (3.5, [0.2..2.3]) + // (4, 1) + } ++ +#ifndef MENUQC +vector cliptoplane(vector v, vector p) +{ + return v - (v * p) * p; +} + +vector solve_cubic_pq(float p, float q) +{ + float D, u, v, a; + D = q*q/4.0 + p*p*p/27.0; + if(D < 0) + { + // irreducibilis + a = 1.0/3.0 * acos(-q/2.0 * sqrt(-27.0/(p*p*p))); + u = sqrt(-4.0/3.0 * p); + // a in range 0..pi/3 + // cos(a) + // cos(a + 2pi/3) + // cos(a + 4pi/3) + return + u * + ( + '1 0 0' * cos(a + 2.0/3.0*M_PI) + + + '0 1 0' * cos(a + 4.0/3.0*M_PI) + + + '0 0 1' * cos(a) + ); + } + else if(D == 0) + { + // simple + if(p == 0) + return '0 0 0'; + u = 3*q/p; + v = -u/2; + if(u >= v) + return '1 1 0' * v + '0 0 1' * u; + else + return '0 1 1' * v + '1 0 0' * u; + } + else + { + // cardano + u = cbrt(-q/2.0 + sqrt(D)); + v = cbrt(-q/2.0 - sqrt(D)); + return '1 1 1' * (u + v); + } +} +vector solve_cubic_abcd(float a, float b, float c, float d) +{ + // y = 3*a*x + b + // x = (y - b) / 3a + float p, q; + vector v; + p = (9*a*c - 3*b*b); + q = (27*a*a*d - 9*a*b*c + 2*b*b*b); + v = solve_cubic_pq(p, q); + v = (v - b * '1 1 1') * (1.0 / (3.0 * a)); + if(a < 0) + v += '1 0 -1' * (v_z - v_x); // swap x, z + return v; +} + +vector findperpendicular(vector v) +{ + vector p; + p_x = v_z; + p_y = -v_x; + p_z = v_y; + return normalize(cliptoplane(p, v)); +} + +vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle) +{ + float sigma; + vector v1, v2; + float dx, dy, r; + float sstyle; + spread *= spreadfactor; //g_weaponspreadfactor; + if(spread <= 0) + return forward; + sstyle = spreadstyle; //autocvar_g_projectiles_spread_style; + + if(sstyle == 0) + { + // this is the baseline for the spread value! + // standard deviation: sqrt(2/5) + // density function: sqrt(1-r^2) + return forward + randomvec() * spread; + } + else if(sstyle == 1) + { + // same thing, basically + return normalize(forward + cliptoplane(randomvec() * spread, forward)); + } + else if(sstyle == 2) + { + // circle spread... has at sigma=1 a standard deviation of sqrt(1/2) + sigma = spread * 0.89442719099991587855; // match baseline stddev + v1 = findperpendicular(forward); + v2 = cross(forward, v1); + // random point on unit circle + dx = random() * 2 * M_PI; + dy = sin(dx); + dx = cos(dx); + // radius in our dist function + r = random(); + r = sqrt(r); + return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); + } + else if(sstyle == 3) // gauss 3d + { + sigma = spread * 0.44721359549996; // match baseline stddev + // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right + v1 = forward; + v1_x += gsl_ran_gaussian(sigma); + v1_y += gsl_ran_gaussian(sigma); + v1_z += gsl_ran_gaussian(sigma); + return v1; + } + else if(sstyle == 4) // gauss 2d + { + sigma = spread * 0.44721359549996; // match baseline stddev + // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right + v1_x = gsl_ran_gaussian(sigma); + v1_y = gsl_ran_gaussian(sigma); + v1_z = gsl_ran_gaussian(sigma); + return normalize(forward + cliptoplane(v1, forward)); + } + else if(sstyle == 5) // 1-r + { + sigma = spread * 1.154700538379252; // match baseline stddev + v1 = findperpendicular(forward); + v2 = cross(forward, v1); + // random point on unit circle + dx = random() * 2 * M_PI; + dy = sin(dx); + dx = cos(dx); + // radius in our dist function + r = random(); + r = solve_cubic_abcd(-2, 3, 0, -r) * '0 1 0'; + return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); + } + else if(sstyle == 6) // 1-r^2 + { + sigma = spread * 1.095445115010332; // match baseline stddev + v1 = findperpendicular(forward); + v2 = cross(forward, v1); + // random point on unit circle + dx = random() * 2 * M_PI; + dy = sin(dx); + dx = cos(dx); + // radius in our dist function + r = random(); + r = sqrt(1 - r); + r = sqrt(1 - r); + return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); + } + else if(sstyle == 7) // (1-r) (2-r) + { + sigma = spread * 1.224744871391589; // match baseline stddev + v1 = findperpendicular(forward); + v2 = cross(forward, v1); + // random point on unit circle + dx = random() * 2 * M_PI; + dy = sin(dx); + dx = cos(dx); + // radius in our dist function + r = random(); + r = 1 - sqrt(r); + r = 1 - sqrt(r); + return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); + } + else + error("g_projectiles_spread_style must be 0 (sphere), 1 (flattened sphere), 2 (circle), 3 (gauss 3D), 4 (gauss plane), 5 (linear falloff), 6 (quadratic falloff), 7 (stronger falloff)!"); + return '0 0 0'; + /* + * how to derive falloff functions: + * rho(r) := (2-r) * (1-r); + * a : 0; + * b : 1; + * rhor(r) := r * rho(r); + * cr(t) := integrate(rhor(r), r, a, t); + * scr(t) := integrate(rhor(r) * r^2, r, a, t); + * variance : scr(b) / cr(b); + * solve(cr(r) = rand * cr(b), r), programmmode:false; + * sqrt(0.4 / variance), numer; + */ +} +#endif diff --cc qcsrc/common/util.qh index 050bb2b4f8,3ce173bf63..8abd36ece0 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@@ -322,6 -321,16 +322,18 @@@ void queue_to_execute_next_frame(strin // for marking written-to values as unused where it's a good idea to do this noref float unused_float; - - + // a function f with: + // f(0) = 0 + // f(1) = 1 + // f'(0) = startspeedfactor + // f'(1) = endspeedfactor + float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x); + + // checks whether f'(x) = 0 anywhere from 0 to 1 + // because if this is the case, the function is not usable for platforms + // as it may exceed 0..1 bounds, or go in reverse + float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor); ++ +#ifndef MENUQC +vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle) +#endif