# GMLscripts.com

Discuss and collaborate on GML scripts

You are not logged in.

## #1 2010-04-09 14:23:47

brac37
Member
Registered: 2010-02-12
Posts: 18

### Reflection of trianglestrips.

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);
}

Offline

## #2 2010-04-15 14:47:16

xot
Registered: 2007-08-18
Posts: 1,240

### Re: Reflection of trianglestrips.

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

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?

Abusing forum power since 1986.

Offline

## #3 2010-07-02 14:34:46

brac37
Member
Registered: 2010-02-12
Posts: 18

### Re: Reflection of trianglestrips.

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.

Offline

## #4 2010-07-02 16:02:20

xot
Registered: 2007-08-18
Posts: 1,240

### Re: Reflection of trianglestrips.

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

Whoops. It's obvious when you know.

he draws the sprite with tiny alpha to set the z-buffer

Ah, I get it. That's way better and very flexible. You could get an even nicer effect with a more smoothly animated mask or possibly a series of masks and more than two reflection images.

Abusing forum power since 1986.

Offline