# GMLscripts.com

Discuss and collaborate on GML scripts

You are not logged in.

## #1 Re: Script Submission » ds_grid_set_grid_disk() » 2013-09-25 17:11:29

The scripts seem a little inefficient to me. The dx and dy can be rounded, so that you do not need to round later. But there is no need to use ii and jj in the loops. Instead, you can adapt x0,x1,y0,y1 such that i + dx and j + dy are always within the destination. The use of a grid copy seems unnecessary, because it is not modified, so that the source can be used directly.

For numerical grids, things can be done more efficiently. For instance, setting can be done by first multiplying the mask by source, next multiplying the destination by the anti-mask, and at last adding the multiplied mask to the destination.

Although operations with both strings and numbers do not seem to work with grids, you can multiply a number by a string to get the string repeated. Now that you are looping anyway, it is an option to use * instead of ds_grid_multiply, so that string grids can be multiplied by numerical grids at some disk.

## #2 Re: Script Alumni » exp_dist(x) » 2013-08-23 20:55:56

On http://en.wikipedia.org/wiki/Exponential_distribution, I read that the exponential distribution gives numbers from 0 to infinity in any case, i.e. the distribution is not bounded. Its  probability density function is r.exp(-rx), where r is the rate parameter.

For the cumulative distribution function, we have y = 1 - exp(-rx). This is equivalent to x = -ln(1-y)/r, so I would suggest to divide by argument0 instead of to multiply.

If you think about it, the larger the rate, the faster the density function goes to zero when x gets larger, the fewer values that exceed some bound. So it must indeed be a downscale.

EDIT: see also http://stackoverflow.com/questions/2106 … stribution. So the current form is used as well.

## #3 Re: Script Submission » HSV_shift » 2013-08-21 18:03:46

The modulus operand for the hue is indeed 255. 0 and 255 are both accepted for red. 85 is green and 170 is blue. I do not know what GM does with out of range hue.

## #4 Script Submission » line_xtoy and line_ytox » 2013-08-21 17:50:10

brac37
Replies: 1

Some easy scripts. But they might be useful.

Expand/*
**  Usage:
**      y3 = line_xtoy  (x1,y1, x2,y2, x3)
**
**  Arguments:
**      x1,y1, x2,y2:       coordinates of two points of the line
**      x3:                 x coordinate of third point of the line
**
**  Returns:
**      y coordinate of third point of the line
**
**
**  brac37
*/
{
return ((argument4-argument0)*argument3 +
(argument2-argument4)*argument1) /
(argument2-argument0);
}
Expand/*
**  Usage:
**      x3 = line_xtoy  (x1,y1, x2,y2, y3)
**
**  Arguments:
**      x1,y1, x2,y2:       coordinates of two points of the line
**      y3:                 y coordinate of third point of the line
**
**  Returns:
**      x coordinate of third point of the line
**
**
**  brac37
*/
{
return ((argument4-argument1)*argument2 +
(argument3-argument4)*argument0) /
(argument3-argument1);
}

## #5 Re: GML Code Help » True Physics Slopes. Engine Done, Optimising Time. » 2010-12-28 13:31:50

xot wrote:

This is such an intriguing post, I really want to see your project. I don't yet have GM8 though. Can you post an executable that I can look at?

I guess I better register GM8 soon, I feel like I'm getting left behind. Next big pay day I'll do that, I'm just not sure when that will be.

You should get it for free, just as any other moderator. Your work for YYG exceeds the costs of GM8 by several dozens of times.

## #6 Re: Script Submission » Some of my 3d Scripts » 2010-08-30 10:39:19

icuurd12b42 wrote:

that is weird xot... I did benchmarking on gm7 a long time ago and (x1-x2) * (x1-x2) was faster than sqr (x1-x2) at least for me.

At least I'm not a liar when it comes to using the point_distance method... same method for zdirection...

Are you sure you were not comparing x1*x1 to sqr(x1) instead?

## #7 Re: Script Submission » Some of my 3d Scripts » 2010-08-28 14:57:46

Obscurely, the point_distance formula requires an extra squaring, an extra subtraction and an extra square root, compared to standard. It should be faster, it seems that GM optimization is more crap than I thought. Furthermore,  attempting to reduce larger arithmetic operations such as sqrt and / compared to + and * appears to be pointless in GM.

## #8 Re: Script Submission » Some of my 3d Scripts » 2010-08-27 18:28:32

paul23 wrote:

hmm not too sure these are the fastest methods: you could also use 2 times lengthdir_* which might be a lot faster?

ie the lengthdir_x_3d would then be:

Expandreturn lengthdir_x(lengthdir_x(argument0,argument2),argument1);

for y:

Expandreturn lengthdir_y(lengthdir_x(argument0,argument2),argument1);

and z:

Expandreturn lengthdir_y(argument0,argument1);

This is from top of my head though, untested =/.

In the same manner and equally untested:

point_zdirection:

Expandreturn point_direction(0,argument5,point_distance(argument0,argument1,argument3,argument4),argument2);

## #9 Re: Script Submission » get_quadratic » 2010-07-02 16:22:36

The following script can compute polynomials for arbitrary number of points, but is very sensitive to rounding errors. It adds polynomials that are zero for all values of x except one.

Expand/*
**  Usage:
**      list = get_polynomic(n,x0,y0,x1,y1,...,xn,yn);
**
**  Arguments:
**      x0, y0      first point on the poly graph
**      x1, y1      second point on the poly graph
**      ...
**      xn, yn      last point on the poly graph
**
**  returns:
**      list        ds_list containing the coefficients of the polynomial,
**                  indexed by the exponent of x they belong to
**          - OR -
**      -1          when no solution can be found.
*/
{
var n, point_x, point_y, point_poly, poly;
var i, v, l;

n = argument0;
for (i=0; i<=n; i+=1) {
point_x[i] = argument[2*i+1];
point_y[i] = argument[2*i+2];
poly[i] = 0;
}

for (i=0; i<=n; i+=1) {
v = 1;
for (j=0; j<i; j+=1) v *= (point_x[i]-point_x[j]);
for (j=i+1; j<=n; j+=1) v *= (point_x[i]-point_x[j]);
if (v == 0) return -1;

point_poly[0] = point_y[i]/v;
for (j=0; j<i; j+=1) {
point_poly[j+1] = point_poly[j];
for (k=j; k>0; k-=1) {
point_poly[k] *= -point_x[j];
point_poly[k] += point_poly[k-1];
}
point_poly[0] *= -point_x[j];
}
for (j=i+1; j<=n; j+=1) {
point_poly[j] = point_poly[j-1];
for (k=j-1; k>0; k-=1) {
point_poly[k] *= -point_x[j];
point_poly[k] += point_poly[k-1];
}
point_poly[0] *= -point_x[j];
}

for (j=0; j<=n; j+=1) poly[j] += point_poly[j];
}

l = ds_list_create ();
for (i=0; i<=n; i+=1) ds_list_add (l, poly[i]);
return l;
}

## #10 Re: Script Submission » Reflection of trianglestrips. » 2010-07-02 14:34:46

xot wrote:

These are a really great idea. Looks like one of the scripts is listed twice, unless I'm missing something.

Yeah, you missed there are two versions: one with normals and one without.

xot wrote:

The demo on GMC is very cool. I especially like how you were able to animate the water. I gather it is exploiting some kind of glitch but I don't really get what's going on. Is that an effected created through z-fighting?

The water animation is not mine, but by rivosaar. He uses a sprite that is half transparent and animated in a "continuous" manner. Next, he draws the sprite with tiny alpha to set the z-buffer where the sprite is opaque. With that, he combines two drawings of the mirrored sky.

## #11 Script Submission » Reflection of trianglestrips. » 2010-04-09 14:23:47

brac37
Replies: 3

Hello all,

I wrote scripts for reflecting trianglestrips. The hardest about that is to cut out the part that is behind the mirror. See also http://gmc.yoyogames.com/index.php?showtopic=444886

Expand/*
**  Usage:
**      d3d_model_primitive_reflection_begin (ind, mode, nx, ny, nz, lev)
**
**  Arguments:
**      ind:            index of model
**      mode:           0 = reflect, 1 = no reflect,
**                      2 = reflect except for normals
**      nx, ny, nz:     normal of plane of reflection (optional)
**      lev:            level of plane of reflection
**                      { (x,y,z) | nx * x + ny * y + nz * z = lev }
**
**  Returns:
**      nothing
**
**  Notes:
**      A trianglestrip is created. Use this function along with
**      d3d_model_vertex_reflection (), d3d_model_vertex_normal_reflection ()
**      and d3d_model_primitive_reflection_end ().
**      Vertexes { (x,y,z) | nx * x + ny * y + nz * z > lev } of the shape
**      are reflected. Vertexes { (x,y,z) | nx * x + ny * y + nz * z > lev }
**      of the shape are cut out. This is useful for making reflections of
**      models.
**
**  brac37
*/
{
var i, n;

i = argument0;
_reflect[i] = argument1 ^ 1;
if (_reflect[i] & 1) _reflect[i] ^= 2;
_planenx[i] = argument2;
_planeny[i] = argument3;
_planenz[i] = argument4;
_planene[i] = argument5;

if (_planenx[i] == 0 and _planeny[i] == 0 and _planenz[i] == 0) {
_planenz[i] = 1;
}
n = sqrt (2 / (sqr(_planenx[i]) + sqr(_planeny[i]) + sqr(_planenz[i])));
_planenx[i] *= n;
_planeny[i] *= n;
_planenz[i] *= n;
_planene[i] *= n;

d3d_model_primitive_begin(i, pr_trianglestrip);
_nvertices[i] = 0;
_lastnx[i] = 0;
_lastny[i] = 0;
_lastnz[i] = 0;
_thisnx[i] = 0;
_thisny[i] = 0;
_thisnz[i] = 0;
}
Expand/*
**  Usage:
**      d3d_model_vertex_reflection (ind, x, y, z, u, v, c, a)
**
**  Arguments:
**      ind:            index of model
**      x, y, z:        coordinates of vertex
**      u, v:           texture coordinates of vertex (optional)
**      c, a:           color and alpha of vertex (optional)
**
**  Returns:
**      nothing
**
**  Notes:
**      See d3d_model_primitive_reflection_begin ().
**
**  brac37
*/
{
var i;
i = argument0;
if (_nvertices[i] > 1) {
_lastx[i] = _thisx[i];
_lasty[i] = _thisy[i];
_lastz[i] = _thisz[i];
_lastne[i] = _thisne[i];
_lastu[i] = _thisu[i];
_lastv[i] = _thisv[i];
_lastc[i] = _thisc[i];
_lasta[i] = _thisa[i];
}
if (_nvertices[i] > 0) {
_thisx[i] = _nextx[i];
_thisy[i] = _nexty[i];
_thisz[i] = _nextz[i];
_thisne[i] = _nextne[i];
_thisu[i] = _nextu[i];
_thisv[i] = _nextv[i];
_thisc[i] = _nextc[i];
_thisa[i] = _nexta[i];
}
_nextx[i] = argument1;
_nexty[i] = argument2;
_nextz[i] = argument3;
_nextu[i] = argument4;
_nextv[i] = argument5;
_nextc[i] = argument6;
_nexta[i] = argument7;
if (_nextc[i] == 0 and _nexta[i] == 0 and argument8 == 0) {
_nextc[i] = c_white;
_nexta[i] = 1;
}
_nextne[i] = _planenx[i]*_nextx[i] + _planeny[i]*_nexty[i] +
_planenz[i]*_nextz[i] - _planene[i];
if (_reflect[i] & 1) {
_nextx[i] -= _nextne[i]*_planenx[i];
_nexty[i] -= _nextne[i]*_planeny[i];
_nextz[i] -= _nextne[i]*_planenz[i];
}

var w1, w2;
if (_nvertices[i] == 1) {
_parity[i] = 0;
if (_thisne[i] >= 0) {
d3d_model_vertex_texture_color (i,_thisx[i],_thisy[i],_thisz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
if (_reflect[i] & 1) {
d3d_model_vertex_texture_color (i,_thisx[i],_thisy[i],_thisz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
}
} else if (_nextne[i] >= 0) {
w2 = _thisne[i]/(_thisne[i]-_nextne[i]);
w1 = 1 - w2;
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
if (_reflect[i] & 1) {
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
}
}
} else if (_nvertices[i] > 1) {
if (_parity[i] == 0 and _thisne[i] >= 0) {
d3d_model_vertex_texture_color (i,_thisx[i],_thisy[i],_thisz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
_parity[i] = 1;
} else if (_thisne[i] < 0 and _lastne[i] >= 0) {
w2 = _thisne[i]/(_thisne[i]-_lastne[i]);
w1 = 1 - w2;
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_lastx[i]*w2,
_thisy[i]*w1+_lasty[i]*w2,_thisz[i]*w1+_lastz[i]*w2,
_thisu[i]*w1+_lastu[i]*w2,_thisv[i]*w1+_lastv[i]*w2,
merge_color(_thisc[i],_lastc[i],w2),
_thisa[i]*w1+_lasta[i]*w2);
if (_parity[i] and _nextne[i] >= 0) {
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_lastx[i]*w2,
_thisy[i]*w1+_lasty[i]*w2,_thisz[i]*w1+_lastz[i]*w2,
_thisu[i]*w1+_lastu[i]*w2,_thisv[i]*w1+_lastv[i]*w2,
merge_color(_thisc[i],_lastc[i],w2),
_thisa[i]*w1+_lasta[i]*w2);
}
_parity[i] = 1;
}
if (_lastne[i]*_nextne[i] <= 0 or (_lastne[i] >= 0 and _thisne[i] < 0)) {
if (_lastne[i] < 0 and _thisne[i] < 0) {
d3d_model_primitive_end (i);
d3d_model_primitive_begin (i, pr_trianglestrip);
_parity[i] = (_nvertices[i] & 1) == (_reflect[i] & 1);
}
w2 = abs(_lastne[i])/(abs(_lastne[i])+abs(_nextne[i]));
w1 = 1 - w2;
d3d_model_vertex_texture_color (i,_lastx[i]*w1+_nextx[i]*w2,
_lasty[i]*w1+_nexty[i]*w2,_lastz[i]*w1+_nextz[i]*w2,
_lastu[i]*w1+_nextu[i]*w2,_lastv[i]*w1+_nextv[i]*w2,
merge_color(_lastc[i],_nextc[i],w2),
_lasta[i]*w1+_nexta[i]*w2);
if (_parity[i] == 0) {
d3d_model_vertex_texture_color (i,_lastx[i]*w1+_nextx[i]*w2,
_lasty[i]*w1+_nexty[i]*w2,_lastz[i]*w1+_nextz[i]*w2,
_lastu[i]*w1+_nextu[i]*w2,_lastv[i]*w1+_nextv[i]*w2,
merge_color(_lastc[i],_nextc[i],w2),
_lasta[i]*w1+_nexta[i]*w2);
}
_parity[i] = 0;
}
if (_parity[i] == 0 and _thisne[i] >= 0) {
d3d_model_vertex_texture_color (i,_thisx[i],_thisy[i],_thisz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
} else if (_nextne[i] >= 0 and _thisne[i] < 0) {
w2 = _thisne[i]/(_thisne[i]-_nextne[i]);
w1 = 1 - w2;
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
if (_parity[i]) {
d3d_model_vertex_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
}
_parity[i] = 0;
} else {
_parity[i] = not _parity[i];
}
}
_nvertices[i] += 1;
}
Expand/*
**  Usage:
**      d3d_model_vertex_normal_reflection (ind, x, y, z, nx, ny, nz,
**                                          u, v, c, a)
**
**  Arguments:
**      ind:            index of model
**      x, y, z:        coordinates of vertex
**      nx, ny, nz:     coordinates of vertex normal
**      u, v:           texture coordinates of vertex (optional)
**      c, a:           color and alpha of vertex (optional)
**
**  Returns:
**      nothing
**
**  Notes:
**      See d3d_model_primitive_reflection_begin ().
**
**  brac37
*/
{
var i;
i = argument0;
if (_nvertices[i] > 1) {
_lastx[i] = _thisx[i];
_lasty[i] = _thisy[i];
_lastz[i] = _thisz[i];
_lastnx[i] = _thisnx[i];
_lastny[i] = _thisny[i];
_lastnz[i] = _thisnz[i];
_lastne[i] = _thisne[i];
_lastu[i] = _thisu[i];
_lastv[i] = _thisv[i];
_lastc[i] = _thisc[i];
_lasta[i] = _thisa[i];
}
if (_nvertices[i] > 0) {
_thisx[i] = _nextx[i];
_thisy[i] = _nexty[i];
_thisz[i] = _nextz[i];
_thisnx[i] = _nextnx[i];
_thisny[i] = _nextny[i];
_thisnz[i] = _nextnz[i];
_thisne[i] = _nextne[i];
_thisu[i] = _nextu[i];
_thisv[i] = _nextv[i];
_thisc[i] = _nextc[i];
_thisa[i] = _nexta[i];
}
_nextx[i] = argument1;
_nexty[i] = argument2;
_nextz[i] = argument3;
_nextnx[i] = argument4;
_nextny[i] = argument5;
_nextnz[i] = argument6;
_nextu[i] = argument7;
_nextv[i] = argument8;
_nextc[i] = argument9;
_nexta[i] = argument10;
if (_nextc[i] == 0 and _nexta[i] == 0 and argument11 == 0) {
_nextc[i] = c_white;
_nexta[i] = 1;
}
if (_reflect[i] & 2) {
_nextne[i] = _planenx[i]*_nextnx[i] + _planeny[i]*_nextny[i] +
_planenz[i]*_nextnz[i];
_nextnx[i] -= _nextne[i]*_planenx[i];
_nextny[i] -= _nextne[i]*_planeny[i];
_nextnz[i] -= _nextne[i]*_planenz[i];
}
_nextne[i] = _planenx[i]*_nextx[i] + _planeny[i]*_nexty[i] +
_planenz[i]*_nextz[i] - _planene[i];
if (_reflect[i] & 1) {
_nextx[i] -= _nextne[i]*_planenx[i];
_nexty[i] -= _nextne[i]*_planeny[i];
_nextz[i] -= _nextne[i]*_planenz[i];
}

var w1, w2, n, nx, ny, nz;
if (_nvertices[i] == 1) {
_parity[i] = 0;
if (_thisne[i] >= 0) {
d3d_model_vertex_normal_texture_color (i,_thisx[i],_thisy[i],
_thisz[i],_thisnx[i],_thisny[i],_thisnz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
if (_reflect[i] & 1) {
d3d_model_vertex_normal_texture_color (i,_thisx[i],_thisy[i],
_thisz[i],_thisnx[i],_thisny[i],_thisnz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
}
} else if (_nextne[i] >= 0) {
w2 = _thisne[i]/(_thisne[i]-_nextne[i]);
w1 = 1 - w2;
nx = _thisnx[i]*w1+_nextnx[i]*w2;
ny = _thisny[i]*w1+_nextny[i]*w2;
nz = _thisnz[i]*w1+_nextnz[i]*w2;
n = 1/sqrt(sqr(nx)+sqr(ny)+sqr(nz));
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
if (_reflect[i] & 1) {
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
}
}
} else if (_nvertices[i] > 1) {
if (_parity[i] == 0 and _thisne[i] >= 0) {
d3d_model_vertex_normal_texture_color (i,_thisx[i],_thisy[i],
_thisz[i],_thisnx[i],_thisny[i],_thisnz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
_parity[i] = 1;
} else if (_thisne[i] < 0 and _lastne[i] >= 0) {
w2 = _thisne[i]/(_thisne[i]-_lastne[i]);
w1 = 1 - w2;
nx = _thisnx[i]*w1+_lastnx[i]*w2;
ny = _thisny[i]*w1+_lastny[i]*w2;
nz = _thisnz[i]*w1+_lastnz[i]*w2;
n = 1/sqrt(sqr(nx)+sqr(ny)+sqr(nz));
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_lastx[i]*w2,
_thisy[i]*w1+_lasty[i]*w2,_thisz[i]*w1+_lastz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_lastu[i]*w2,_thisv[i]*w1+_lastv[i]*w2,
merge_color(_thisc[i],_lastc[i],w2),
_thisa[i]*w1+_lasta[i]*w2);
if (_parity[i] and _nextne[i] >= 0) {
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_lastx[i]*w2,
_thisy[i]*w1+_lasty[i]*w2,_thisz[i]*w1+_lastz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_lastu[i]*w2,_thisv[i]*w1+_lastv[i]*w2,
merge_color(_thisc[i],_lastc[i],w2),
_thisa[i]*w1+_lasta[i]*w2);
}
_parity[i] = 1;
}
if (_lastne[i]*_nextne[i] <= 0 or (_lastne[i] >= 0 and _thisne[i] < 0)) {
if (_lastne[i] < 0 and _thisne[i] < 0) {
d3d_model_primitive_end (i);
d3d_model_primitive_begin (i, pr_trianglestrip);
_parity[i] = (_nvertices[i] & 1) == (_reflect[i] & 1);
}
w2 = abs(_lastne[i])/(abs(_lastne[i])+abs(_nextne[i]));
w1 = 1 - w2;
nx = _lastnx[i]*w1+_nextnx[i]*w2;
ny = _lastny[i]*w1+_nextny[i]*w2;
nz = _lastnz[i]*w1+_nextnz[i]*w2;
n = 1/sqrt(sqr(nx)+sqr(ny)+sqr(nz));
d3d_model_vertex_normal_texture_color (i,_lastx[i]*w1+_nextx[i]*w2,
_lasty[i]*w1+_nexty[i]*w2,_lastz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_lastu[i]*w1+_nextu[i]*w2,_lastv[i]*w1+_nextv[i]*w2,
merge_color(_lastc[i],_nextc[i],w2),
_lasta[i]*w1+_nexta[i]*w2);
if (_parity[i] == 0) {
d3d_model_vertex_normal_texture_color (i,_lastx[i]*w1+_nextx[i]*w2,
_lasty[i]*w1+_nexty[i]*w2,_lastz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_lastu[i]*w1+_nextu[i]*w2,_lastv[i]*w1+_nextv[i]*w2,
merge_color(_lastc[i],_nextc[i],w2),
_lasta[i]*w1+_nexta[i]*w2);
}
_parity[i] = 0;
}
if (_parity[i] == 0 and _thisne[i] >= 0) {
d3d_model_vertex_normal_texture_color (i,_thisx[i],_thisy[i],
_thisz[i],_thisnx[i],_thisny[i],_thisnz[i],
_thisu[i],_thisv[i],_thisc[i],_thisa[i]);
} else if (_nextne[i] >= 0 and _thisne[i] < 0) {
w2 = _thisne[i]/(_thisne[i]-_nextne[i]);
w1 = 1 - w2;
nx = _thisnx[i]*w1+_nextnx[i]*w2;
ny = _thisny[i]*w1+_nextny[i]*w2;
nz = _thisnz[i]*w1+_nextnz[i]*w2;
n = 1/sqrt(sqr(nx)+sqr(ny)+sqr(nz));
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
if (_parity[i]) {
d3d_model_vertex_normal_texture_color (i,_thisx[i]*w1+_nextx[i]*w2,
_thisy[i]*w1+_nexty[i]*w2,_thisz[i]*w1+_nextz[i]*w2,
nx*n,ny*n,nz*n,
_thisu[i]*w1+_nextu[i]*w2,_thisv[i]*w1+_nextv[i]*w2,
merge_color(_thisc[i],_nextc[i],w2),
_thisa[i]*w1+_nexta[i]*w2);
}
_parity[i] = 0;
} else {
_parity[i] = not _parity[i];
}
}
_nvertices[i] += 1;
}
Expand/*
**  Usage:
**      d3d_model_primitive_reflection_end (ind)
**
**  Arguments:
**      ind:            index of model
**
**  Returns:
**      nothing
**
**  Notes:
**      See d3d_model_primitive_reflection_begin ().
**
**  brac37
*/
{
var i;
i = argument0;
if (_nvertices[i] > 2) {
if (_nextne[i] >= 0) {
d3d_model_vertex_normal_texture_color (i,_nextx[i],_nexty[i],
_nextz[i],_nextnx[i],_nextny[i],_nextnz[i],
_nextu[i],_nextv[i],_nextc[i],_nexta[i]);
} else if (_thisne[i] >= 0) {
var w1, w2, n, nx, ny, nz;
w2 = _nextne[i]/(_nextne[i]-_thisne[i]);
w1 = 1 - w2;
nx = _nextnx[i]*w1+_thisnx[i]*w2;
ny = _nextny[i]*w1+_thisny[i]*w2;
nz = _nextnz[i]*w1+_thisnz[i]*w2;
n = 1/sqrt(sqr(nx)+sqr(ny)+sqr(nz));
d3d_model_vertex_normal_texture_color (i,_nextx[i]*w1+_thisx[i]*w2,
_nexty[i]*w1+_thisy[i]*w2,_nextz[i]*w1+_thisz[i]*w2,
nx*n,ny*n,nz*n,
_nextu[i]*w1+_thisu[i]*w2,_nextv[i]*w1+_thisv[i]*w2,
merge_color(_nextc[i],_thisc[i],w2),
_nexta[i]*w1+_thisa[i]*w2);
}
}
d3d_model_primitive_end (i);
}

## #12 Script Submission » shear transform » 2010-03-05 16:43:37

brac37
Replies: 0

Hello all,

I have already submitted the shear script by way of the web interface, but the few d3d-scripts have not changed.
The shear transform has many applications:
1) Anaglyphs. Using rotations for the different eye-views is incorrect. Use shear transforms instead. See http://host-a.net/brac37/fps6anaglyph.gm6
2) Monitor drawing. You can draw a monitor by way of a surface which you use as a texture, but by way of a shear transform, you can draw the image of the monitor directly onto the screen. See http://host-a.net/brac37/fps6monitor.gm6.
3) Shadow drawing. You can draw shadows of point light by way of drawing onto a surface with the point light as the camera. The same holds for directional lights: use orthogonal camera projection. But shadows of directional lights can also by drawn directly on the screen by way of MitchGraham's method: simply project the scene onto the plane that must contain shadows. If the directional light is orthogonal to the plane, then the projection is simple. If not, then the projection is still simple if you use the shear transform script. See http://host-a.net/brac37/Dynamic%20Shadows%20Newer.gmk
And I did not mention drawing something skew yet.

Expand/*
**  Usage:
**
**  Arguments:
**      x, y, z: coordinates
**
**  Returns:
**      nothing
**
**  Notes:
**      The z-axis is made skew: points (0,0,t) are draw at (t*x,t*y,t*z).
**      The x-axis (points (t,0,0)) and the y-axis (points (0,t,0)) stay
**      the same.
**      The skew transformation is added to the current transformation.
**      This transformation is not orthogonal and hence does not work
**      properly in combination with lighting.
**
**  brac37
*/
{
var xs, ys, zs, n, ya, ya2, za;
xs = argument0;
ys = argument1;
zs = argument2;
n = sqrt(sqr(xs) + sqr(ys) + sqr(zs));
za = radtodeg (arctan2 (ys, xs));
ya2 = 0.5 * arctan2 (zs, sqrt(sqr(xs) + sqr(ys)));
}

## #13 Re: Script Submission » Euler's Totient Script » 2010-03-01 23:18:27

Expand/*
**      eulers_totient(number);
**
**      argument0 = a postive real number
**
**  Returns the value of Euler's totient as a real number
**
**  Notes:
**      Euler's totient is how many coprime numbers there are
**      less than the inputted number.
*/
var n,i,et;
n = argument0;
i=2;
et=1;
while (i <= n) {
if (n mod i == 0) {
et *= i - 1;
n /= i;
while (n mod i == 0) {
et *= i;
n /= i;
}
}
i+=1;
}
return et;

EDIT: script was incorrect. Corrected it.

## #14 Re: Script Submission » draw_sprite_origin » 2010-03-01 22:29:19

Expand/*
**  Usage:
**      draw_sprite_origin( sprite, image, x, y, angle, hoff, voff )
**
**  Arguments:
**      0-3       like in draw_sprite
**      angle     rotation
**      hoff      desired horizontal offset of the origin
**      voff      desired vertical offset of the origin
**
**  Example:
**      draw_sprite_origin( sprite_index, image_index, x, y, direction, 0, 0 )
**
**  Returns:
**      nothing
**
**  Notes:
**      Sometimes, you cannot rotate your sprites using their origins
**      Then you use this function
**      d3d does not have to be initiated
**
**  Burunduk and brac37
*/
draw_sprite_origin_ext (argument0, argument1, argument2, argument3, 1, 1, argument4, c_white, 1, argument5, argument6);
Expand/*
**  Usage:
**      draw_sprite_origin_ext(sprite, subimg, x, y, xscale, yscale, rot, color, alpha, hoff, voff )
**
**  Arguments:
**      0-8       same as draw_sprite_ext
**      hoff      desired horizontal offset of the origin
**      voff      desired vertical offset of the origin
**
**  Example:
**      draw_sprite_origin_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, direction, c_white, 1, 0, 0 )
**
**  Returns:
**      nothing
**
**  Notes:
**      Sometimes, you cannot rotate your sprites using their origins
**      Then you use this function
**      The actual origin has to be at 0,0 for this version to work
**      d3d does not have to be initiated
**
**  Burunduk and brac37
*/
var hoff, voff, xx, yy;

// calculate offsets based on origin
hoff = argument9 - sprite_get_xoffset(argument0);
voff = argument10 - sprite_get_yoffset(argument0);

// calculate coordinates
xx = argument2 [+ hoff] - lengthdir_x (hoff, argument6) + lengthdir_y (voff, argument6);
yy = argument3 [+ voff] - lengthdir_x (voff, argument6) - lengthdir_y (hoff, argument6);

//draw sprite
draw_sprite_ext(argument0, argument1, xx, yy, argument4, argument5, argument6, argument7, argument8);

Something like that. I have not tested my code.

EDIT: my code works differently. With my code, the sprite is draw as usual (i.e. on (x - sprite_get_xoffsef, y - sprite_get_yoffset)) if angle = 0, with (x + argument9 - sprite_get_xoffset, y + argument10 - sprite_get_xoffset) being the rotation center on the screen. With Burunduk's code, the rotation center on the screen is (x, y). The rotation center of the sprite is (argument9, argument10) for both scripts. You can get the same behavior if you remove the parts of my script that are between [ and ] now, i.e. [+ hoff] and [+ voff].

## #15 Re: Script Submission » bezier4 » 2010-03-01 21:47:11

xot wrote:

Computes a cubic Bézier curve given a parameter, t, and four control points, {p0,p1,p2,p3}.

$$\mathbf{B}(t)=(1-t)^3\mathbf{P}_0+3(1-t)^2t\mathbf{P}_1+3(1-t)t^2\mathbf{P}_2+t^3\mathbf{P}_3 \mbox{ , } t \in [0,1].$$

Expand//  bezier4(t,p0,p1,p2,p3)
{
argument5 = 1 - argument0;
return
power(argument5,3)                 * argument1 +
power(argument5,2) * 3 * argument0 * argument2 +
power(argument0,2) * 3 * argument5 * argument3 +
power(argument0,3)                 * argument4;
}

Can this be optimized?

Well, one/two times multiplication is faster than second/third power, I would think. Further, the terms in the middle can be factorized.

Expand//  bezier4(t,p0,p1,p2,p3)
{
argument5 = 1 - argument0;
return
sqr(argument5) * argument5 * argument1 +
3 * argument0 * argument5 * (argument5 *
argument2 + argument0 * argument3) +
sqr(argument0 * argument0 * argument4;
}

## #16 Re: GML Reference » Blend Modes » 2010-02-25 18:44:49

There are two other issues. Normal blending does not set the z-buffer when the alpha of the source is zero. You can use blend mode (bm_zero, bm_one) if your only purpose is to change the z-buffer. Are there other blendings that do not set the z-buffer with alpha = 0?

Another issue is blend mode 13. Is it really something different as 1 to 11? Or is it only a tale?

## #17 Re: Game Maker Bugs » median - returns wrong value when using an odd number of arguments » 2010-02-25 18:32:31

As yourself pointed, the median function is useful for bounding a value to an interval: median(lower_bound, value, upper_bound). I guess median(lower_bound, value, upper_bound, upper_bound) works for all versions of game maker.

Sorting an array is too much work to obtain the median or any other "smallest but k" value. Lazy quicksort suffices and takes linear time approximately instead of an extra logarithmic factor. But probably, there is no way to do lazy quicksort without using a slow GML.

There is a faster solution: add max_dbl as an argument.

## #18 Re: Community » Cookie Problems » 2010-02-24 17:43:40

I had a problem signing up with chrome. The error message was that the anti-bot text was incorrect. I used firefox to sign up.