Noticias

Importante: ¡Si quieres publicar tu juego no olvides leer este tema!

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Temas - Clamud

Páginas: 1 2
1
Desarrollo de Scripts / Colorear capa de tiles (blend color)
« en: Marzo 11, 2018, 04:15:44 pm »
Autor: Clamud
Versión: :GM8: :GMS:
Descripción: Establece el "blend color" de una capa de tiles.

tile_layer_blend( depth, tileWidth, tileHeight, color );
/// tile_layer_blend( depth, tileWidth, tileHeight, color );
/*                    0      1          2           3
Estable el color de una capa de tiles.

Argumentos | Descripción
---------------------------------------------
depth      | Profundidad de la capa de tiles
tileWidth  | Anchura de las tiles
tileHeight | Altura de las tiles
color      | Color para mezclar
*/

// inicializar variables
var _tileList = ds_list_create();
var _tileCount = 0;
var _tileId, _x, _y;

for (_y=0; _y<room_height; _y+=argument2) //escaneo vertical
for (_x=0; _x<room_width; _x+=argument1) //escaneo horizontal
{
   _tileId = tile_layer_find(argument0, _x,_y); //buscar tile
   if (_tileId <> -1) //si hay tile en esta posicion
   {
      ds_list_add(_tileList, _tileId); //agregar a la lista
      _tileCount ++; //incrementar contador
   }
}

// asignar color a todas las tiles encontradas
for (_x=0; _x<_tileCount; _x++)
{
   _tileId = ds_list_find_value(_tileList, _x);
   tile_set_blend(_tileId, argument3);
}

// destruir lista
ds_list_destroy(_tileList);

Ejemplo
tile_layer_blend(200, 16, 16, c_purple);

2
Desarrollo de Scripts / Copiar sprite en blanco
« en: Abril 27, 2016, 06:59:13 pm »
Autor: Clamud, basado en algunos scripts de gmlscripts.com
Versión: :GM8:
Descripción: Crea una copia del sprite indicado, pero los pixeles no transparentes se hacen blancos.

sprite_blanco( spr );
///sprite_blanco( spr );
//Copia el sprite indicado, en blanco
//Devuelve el indice del nuevo sprite creado
//NOTA: el blend_mode se hace normal

var s, w, h, xo, yo, sf, i, s2;

s = argument0; //sprite
w = sprite_get_width(s); //anchura
h = sprite_get_height(s); //altura
n = sprite_get_number(s); //numero de sub-imagenes
xo = sprite_get_xoffset(s); //origen x
yo = sprite_get_yoffset(s); //origen y

sf = surface_create(w,h); //superficie
surface_set_target(sf); //establecer como lienzo
draw_set_blend_mode_ext( bm_zero, bm_src_alpha ); //copiar alfa

for( i=0; i<n; i+=1 )
{
    draw_clear( c_white ); //llenar de color blanco
    draw_sprite( s,i, xo,yo ); //copiar alfa
    if( i == 0 ) s2 = sprite_create_from_surface( sf, 0,0, w,h, false,false, xo,yo );
    else sprite_add_from_surface( s2,sf, 0,0, w,h, false,false );
}

draw_set_blend_mode( bm_normal );
surface_reset_target();
surface_free( sf );

return s2;

3
Desarrollo de Scripts / Punto en rectángulo rotado
« en: Abril 15, 2016, 01:45:55 am »
Autor: Klamud
Versión: :GM8:
Descripción: Define un rectángulo rotado y revisa si un punto está dentro del rectángulo. Lo mismo se puede hacer con image_angle, pero este script debe tener mayor precisión.

punto_en_rect_rotado( x,y, u,v, w,h, px,py, angulo );
///punto_en_rect_rotado( x,y, u,v, w,h, px,py, angulo );
/*                       0 1  2 3  4 5  6  7   8
PUNTO EN RECTANGULO ROTADO
x,y: punto de rotacion en room
u,v: punto de rotacion en rectangulo
w,h: anchura y altura
px,py: punto de prueba
angulo: angulo en grados
*/
var Ax,Ay, Bx,By;

//vector A
Ax = argument6 - argument0;
Ay = argument7 - argument1;

//rotar vector y sumar uv
Bx = lengthdir_x(Ax,argument8) + lengthdir_y(Ay,argument8) + argument2;
By = lengthdir_x(Ay,argument8) - lengthdir_y(Ax,argument8) + argument3;

//resultado
return Bx>0 and Bx<argument4 and By>0 and By<argument5;

Ejemplo adjunto.

4
Desarrollo de Scripts / Crear matriz a partir una cadena
« en: Abril 12, 2016, 08:29:23 pm »
Autor: Clamud
Versión: GameMaker Studio
Descripción: Crea una matriz 2D de números reales a partir de una cadena, usa 'coma' para separar las columnas y 'punto y coma' para separar las filas. Se pueden usar espacios, puntos decimales y saltos de línea. La cadena debe terminar con 'punto y coma'.

string_matrix( string )
///string_matrix( string );
/*
  Crea una matriz 2D a partir de una cadena
  , separa las columnas
  ; separa los renglones
*/

var cad = argument0; //cadena
var lon = string_length(cad); //longitud
var pos; //posicion
var mat; //matriz
var car; //caracter
var sub = ""; //sub-cadena
var i=0, j=0; //indices

for( pos=1; pos<=lon; pos++ ) //para todos los caracteres
{
    car = string_char_at( cad, pos );
    if( car == "," ){ //si es coma
        mat[i,j] = real(sub); //agregar valor a la matriz
        sub = ""; //borrar sub-cadena
        i++; //incrementar indice
    }
    else if( car == ";" ){ //si es punto y coma
        mat[i,j] = real(sub); //agregar valor a la matriz
        sub = ""; //borrar sub-cadena
        i = 0; //reiniciar i
        j++; //incrementar j
    }
    else sub += car; //agregar caracter a sub-cadena
}
return mat; //devolver matriz

Ejemplo:
Matrix = string_matrix("
1.10, 2.00, 3.14, 4.00;
5.00, 6.66, 7.00, 8.00;
9.22, 10.0, 11.1, 12.9;
");

5
Desarrollo de Scripts / Dibujar sector circular
« en: Abril 11, 2016, 08:13:21 pm »
Autor: yo
Descripción: Dibuja un sector circular o "queso partido"
Versión: GM8 en adelante, también podría funcionar en versiones previas

Código:
///dibujar_sector( x,y,r, a1,a2,a3, contorno );
/*                 0 1 2  3  4  5   6
DIBUJAR UN SECTOR CIRULAR
Dibuja un sector circular con vertice en (x,y), el vertice
es el centro del circulo, con radio r. El area dibujada va
desde el angulo 1 (a1) hasta el angulo 2 (a2), en el sentido
contrario a las manecillas del reloj, en incrementos iguales
al angulo 3 (a3). Si se intercambian los valores de a1 y a2
el sector resultante es el conjugado del primero.

Argumentos
   x,y: vertice del sector
   r: radio
   a1: angulo inicial
   a2: angulo final
   a3: angulo incremento (precision)
   contorno: dibujar solo contorno o llenar poligono
   
Devuelve: nada
*/
var xx, yy, r, a1, a2, a3;
xx = argument0; //vertice
yy = argument1;
r  = argument2; //radio

a1 = argument3; //angulo inicial
a2 = argument4; //angulo final
while( a1 > a2 ) a2 += 360; //evitar sectores mayores
while( a2-a1 > 360 ) a1 += 360; // a 360 grados

if( argument5 == 0 ) a3 = 10; //la precision debe
else a3 = abs(argument5); // ser mayor a cero

//iniciar primitivas (contorno o lleno)
if( argument6 ) draw_primitive_begin( pr_linestrip );
else draw_primitive_begin( pr_trianglefan );

draw_vertex( xx, yy ); //primer vertice
while( a2 >= a1 ) //hacer un barrido desde a2 hasta a1
{
    draw_vertex(
    xx + lengthdir_x(r,a2),
    yy + lengthdir_y(r,a2) );
    a2 -= a3;
}
draw_vertex( //vertice en a1
xx + lengthdir_x(r,a1),
yy + lengthdir_y(r,a1) );

if( argument6 ) draw_vertex( xx, yy ); //vertice final
draw_primitive_end();

6
Preguntas y respuestas / Aceleración y fricción en 2D
« en: Octubre 04, 2015, 04:14:46 am »
Hola a todos.

Estaba buscando ideas para programar un movimiento suave en 2D, para un shooter cenital. El personaje alcanza grandes velocidades y, para tener un buen control, es necesario un cambio gradual de velocidad, también se pretende simular al personaje derrapando porque no puede detenerse al instante. El programa también podría simular el desplazamiento sobre hielo.

Lo que se hace comúnmente para programar ese comportamiento es dar un valor a la variable friction y después sumar una velocidad para modificar las variables speed y direction. El valor de speed se incrementa en cantidades mayores a friction para poder contrarrestar la fricción, hasta alcanzar una velocidad máxima. Lo que no me agrada de este algoritmo es que el tiempo necesario para alcanzar la velocidad máxima es mayor al tiempo necesario para detenerse por completo, busco un algoritmo que permita acelerar y frenar en tiempos iguales. Además la dirección que se indica con los controles nunca se alcanza, a menos que se inicie el movimiento desde el reposo, la dirección se aproxima mucho, pero no es exacta.

Tengo un algoritmo que ha ido evolucionando conforme lo usaba en diferentes juegos, primero en un FPS, después en un plataformero 3D, y ahora en un shooter cenital. He logrado hacer que el tiempo para acelerar sea igual al tiempo para frenar, y es posible frenar más rápido si se mueve el joystick en la dirección contraria al movimiento. Pero no me gusta demasiado, creo que aún puede mejorar. En este sistema, la velocidad se obtiene como una suma vectorial de dos componentes que he llamado "empuje" e "inercia".

Espero que puedan ayudarme. Más tarde explicaré mi algoritmo.

7
Preguntas y respuestas / Problema con redondeo [solucionado]
« en: Agosto 11, 2015, 03:59:41 am »
Hola, hice un programa para encontrar la circunferencia que pasa por 3 puntos (usando el método de sistema de ecuaciones), pero hay pérdidas debidas al redondeo y en ocasiones, al comparar el radio con las distancias de los puntos al centro de la circunferencia,  no se consideran iguales (usando el operador ==).
A veces las diferencias son insignificantes y los números no se consideran iguales y otras veces las diferencias son de la misma magnitud ¡y si se consideran iguales!.

Si sólo quisiera dibujar el círculo no importaría, el problema es que pienso usar el algoritmo para generar una triangulación de Deloné (o Delaunay) y si no hay seguridad en las comparaciones el sistema se va a complicar mucho.

En GMS el problema se puede solucionar con la función math_set_delta, sin embargo, en GM8 no existe esa función. He pensado en usar string_format para redondear hasta un número fijo de cifras decimales, pero esa función es demasiado lenta y sería necesario usarla en cientos o miles de iteraciones, además hay que hacer comparaciones de intervalos (<, >), entonces se debería usar la función real que también es lenta. Otra solución sería comparar los números a nivel de bits, pero no estoy seguro de cómo hacerlo. ¿Alguien tiene otra idea?

El proyecto está adjunto. Los controles son:
Click izquierdo - agregar un punto
Click derecho - reiniciar
Enter - agregar puntos con el teclado
Espacio - agregar puntos aleatorios

Las siguientes combinaciones de puntos producen resultados diferentes:

una causa error
( 365, 302 )
( 383, 184 )
( 548, 199 )

y la otra no
( 394, 470 )
( 369, 184 )
( 191, 251 )

8
Desarrollo de Scripts / Cuerpos geométricos
« en: Junio 20, 2015, 07:54:35 pm »
Autor: Clamud
Versión: :GM8: 8.1 y :GMS: 1.4
Descripción: Conjunto de scripts para modelar cuerpos geométricos. Son el resultado de varios experimentos hechos en mi juego de planetas.

scDodecaedro( ind, r );
Modela un dodecaedro regular con el radio indicado. Los vértices se calculan como se muestra aquí, y se usan ciclos para hacer las diferentes combinaciones de signos.
Código
///scDodecaedro( ind, r );
/*
MODELAR DODECAEDRO
   ind: indice del modelo
   r: radio del dodecadedro
   
Devuelve: nada
Autor: Clamud
*/
var fi, a,b,c,d,e, i,j,k, i1,i2, v1,v2,v3,v4,v5, n;

fi = (sqrt(5)+1)/2; //número aureo

a = argument1/sqrt(3); //vértices
b = a/fi;
c = a*fi;// b < a < c

d = 1/point_distance(0,0,1,fi); //normales
e = d*fi;// d < e

d3d_model_clear( argument0 );
for( i=0; i<3; i+=1 )// i : {0,1,2}, posición del cero
{
    i1 = (i+1)mod(3); //posición de b
    i2 = (i+2)mod(3); //posición de c
   
    for( j=-1; j<2; j+=2 )// j : {-1,1}, signo de c
    for( k=-1; k<2; k+=2 )// k : {-1,1}, signo de b
    {
        v4[i] = 0;      v4[i1] = k*b;  v4[i2] = j*c;
        v5[i] = 0;      v5[i1] =-k*b;  v5[i2] = j*c;
        v2[i] = j*k*a;  v2[i1] = k*a;  v2[i2] = j*a;
        v3[i] = j*k*a;  v3[i1] =-k*a;  v3[i2] = j*a;
        v1[i] = j*k*c;  v1[i1] = 0;    v1[i2] = j*b;
         n[i] = j*k*d;   n[i1] = 0;     n[i2] = j*e
         
        d3d_model_primitive_begin( argument0, pr_trianglestrip );
        d3d_model_vertex_normal_texture( argument0,  v1[0],v1[1],v1[2], n[0],n[1],n[2], .5+lengthdir_x(.5,90),  .5+lengthdir_y(.5,90) );
        d3d_model_vertex_normal_texture( argument0,  v2[0],v2[1],v2[2], n[0],n[1],n[2], .5+lengthdir_x(.5,18),  .5+lengthdir_y(.5,18) );
        d3d_model_vertex_normal_texture( argument0,  v3[0],v3[1],v3[2], n[0],n[1],n[2], .5+lengthdir_x(.5,162), .5+lengthdir_y(.5,162) );
        d3d_model_vertex_normal_texture( argument0,  v4[0],v4[1],v4[2], n[0],n[1],n[2], .5+lengthdir_x(.5,306), .5+lengthdir_y(.5,306) );
        d3d_model_vertex_normal_texture( argument0,  v5[0],v5[1],v5[2], n[0],n[1],n[2], .5+lengthdir_x(.5,234), .5+lengthdir_y(.5,234) );
        d3d_model_primitive_end( argument0 );
    }
}

scDodecaedroEstrellado( ind, r1, r2 );
Cada cara del dodecaedro se divide en 5 triángulos para formar una punta de estrella; r1 es el radio base y r2 es el radio de cada punta. Requiere el sript scNormal para calcular el vector normal de cada triángulo.
Código
///scDodecaedroEstrellado( ind, r1,r2 );
/*
MODELAR DODECAEDRO ESTRELLADO
   ind: indice del modelo
   r1: radio del dodecadedro base
   r2: radio de las puntas
   
Devuelve: nada
Nota: requiere el script scNormal
Autor: Clamud
*/
var a,b,c,d,e, i,j,k, i1,i2, v1,v2,v3,v4,v5, v0;//, nx,ny,nz;

fi = (sqrt(5)+1)/2; //número aureo

a = argument1/sqrt(3); //vértices
b = a/fi;
c = a*fi; // b < a < c

d = argument2/point_distance(0,0,1,fi); //puntas
e = d*fi; // d < e

d3d_model_clear( argument0 );
for( i=0; i<3; i+=1 )// i : {0,1,2}, posición del cero
{
    i1 = (i+1)mod(3); //posición de b
    i2 = (i+2)mod(3); //posición de c
   
    for( j=-1; j<2; j+=2 )// j : {-1,1}, signo de c
    for( k=-1; k<2; k+=2 )// k : {-1,1}, signo de b
    {
        v4[i] = 0;      v4[i1] = k*b;  v4[i2] = j*c;
        v5[i] = 0;      v5[i1] =-k*b;  v5[i2] = j*c;
        v2[i] = j*k*a;  v2[i1] = k*a;  v2[i2] = j*a;
        v3[i] = j*k*a;  v3[i1] =-k*a;  v3[i2] = j*a;
        v1[i] = j*k*c;  v1[i1] = 0;    v1[i2] = j*b;
        v0[i] = j*k*d;  v0[i1] = 0;    v0[i2] = j*e;
       
        d3d_model_primitive_begin( argument0, pr_trianglelist );
       
        scNormal( v0[0],v0[1],v0[2], v1[0],v1[1],v1[2], v2[0],v2[1],v2[2] );
        d3d_model_vertex_normal_texture( argument0,  v0[0],v0[1],v0[2], nx,ny,nz, .5,.5 );
        d3d_model_vertex_normal_texture( argument0,  v1[0],v1[1],v1[2], nx,ny,nz, .5+lengthdir_x(.5,90),  .5+lengthdir_y(.5,90) );
        d3d_model_vertex_normal_texture( argument0,  v2[0],v2[1],v2[2], nx,ny,nz, .5+lengthdir_x(.5,18),  .5+lengthdir_y(.5,18) );
       
        scNormal( v0[0],v0[1],v0[2], v2[0],v2[1],v2[2], v4[0],v4[1],v4[2] );
        d3d_model_vertex_normal_texture( argument0,  v0[0],v0[1],v0[2], nx,ny,nz, .5,.5 );
        d3d_model_vertex_normal_texture( argument0,  v2[0],v2[1],v2[2], nx,ny,nz, .5+lengthdir_x(.5,18),  .5+lengthdir_y(.5,18) );
        d3d_model_vertex_normal_texture( argument0,  v4[0],v4[1],v4[2], nx,ny,nz, .5+lengthdir_x(.5,306), .5+lengthdir_y(.5,306) );
       
        scNormal( v0[0],v0[1],v0[2], v4[0],v4[1],v4[2], v5[0],v5[1],v5[2] );
        d3d_model_vertex_normal_texture( argument0,  v0[0],v0[1],v0[2], nx,ny,nz, .5,.5 );
        d3d_model_vertex_normal_texture( argument0,  v4[0],v4[1],v4[2], nx,ny,nz, .5+lengthdir_x(.5,306), .5+lengthdir_y(.5,306) );
        d3d_model_vertex_normal_texture( argument0,  v5[0],v5[1],v5[2], nx,ny,nz, .5+lengthdir_x(.5,234), .5+lengthdir_y(.5,234) );
       
        scNormal( v0[0],v0[1],v0[2], v5[0],v5[1],v5[2], v3[0],v3[1],v3[2] );
        d3d_model_vertex_normal_texture( argument0,  v0[0],v0[1],v0[2], nx,ny,nz, .5,.5 );
        d3d_model_vertex_normal_texture( argument0,  v5[0],v5[1],v5[2], nx,ny,nz, .5+lengthdir_x(.5,234), .5+lengthdir_y(.5,234) );
        d3d_model_vertex_normal_texture( argument0,  v3[0],v3[1],v3[2], nx,ny,nz, .5+lengthdir_x(.5,162), .5+lengthdir_y(.5,162) );
       
        scNormal( v0[0],v0[1],v0[2], v3[0],v3[1],v3[2], v1[0],v1[1],v1[2] );
        d3d_model_vertex_normal_texture( argument0,  v0[0],v0[1],v0[2], nx,ny,nz, .5,.5 );
        d3d_model_vertex_normal_texture( argument0,  v3[0],v3[1],v3[2], nx,ny,nz, .5+lengthdir_x(.5,162), .5+lengthdir_y(.5,162) );
        d3d_model_vertex_normal_texture( argument0,  v1[0],v1[1],v1[2], nx,ny,nz, .5+lengthdir_x(.5,90),  .5+lengthdir_y(.5,90) );
       
        d3d_model_primitive_end( argument0 );
    }
}

scTorus( ind, r,R, n,N, hrep,vrep );
Modela un toro (o rosquilla) empleando sus ecuaciones paramétricas; r es el radio menor, R es el radio mayor, n es el número de segmentos en cada anillo, N es el número de anillos, hrep y vrep definen cuantas veces se repite la textura.
Código
///scTorus( ind, r,R, n,N, hrep,vrep );
/*
MODELAR TORUS
   ind: indice del modelo a usar
   r: radio menor (radio del conducto)
   R: radio mayor (radio del trayecto)
   n: cantidad de segmentos en cada anillo
   N: cantidad de anillos
   hrep: repetición horizontal de la textura
   vrep: repetición vertical de la textura
   
Devuelve: nada
Autor: Clamud
*/
var r,R, n,N, hrep,vrep, A,cA,sA, B,cB,sB, t,ct,st;
r = argument1; //radio del conducto
R = argument2; //radio del trayecto
n = max( floor(argument3), 3 ); //por lo menos 3 segmentos
N = max( floor(argument4), 3 ); //por lo menos 3 anillos
hrep = argument5; //repetición de la textura
vrep = argument6;

A  = 0; //= 0*2*pi/N;
cA = 1; //= cos(A);
sA = 0; //= sin(A);
for( i=1; i<=N; i+=1 )
{
    B  = i*2*pi/N; //párametro en la trayectoria
    cB = cos(B);
    sB = sin(B);
    d3d_model_primitive_begin( argument0, pr_trianglestrip );
    for( j=0; j<=n; j+=1 )
    {
        t = pi - j*2*pi/n; //parámetro en el conducto
        ct  = cos(t);
        st  = sin(t);
        d3d_model_vertex_normal_texture( argument0,
            cA*(R+r*ct), -sA*(R+r*ct), r*st,
            cA*ct,       -sA*ct,       st,
            hrep*(i-1)/N, vrep*j/n );
        d3d_model_vertex_normal_texture( argument0,
            cB*(R+r*ct), -sB*(R+r*ct), r*st,
            cB*ct,       -sB*ct,       st,
            hrep*i/N, vrep*j/n );
    }
    d3d_model_primitive_end( argument0 );
    A  = B;
    cA = cB;
    sA = sB;
}

scCuboEsfera1( ind, r, n, hrep, vrep );
Una forma alternativa de modelar una esfera. El algoritmo se puede interpretar de esta forma: se tiene un cubo base que es inflado hasta convertirse en una esfera, de forma más precisa: varios punto en la cara de un cubo se proyectan hacia la superficie de una esfera; r es el radio, n es el número de divisiones (en horizontal y vertical) de cada cara, hrep y vrep definen cuantas veces se repite la textura.
Código
///scCuboEsfera1( ind, r, n, hrep, vrep );
/*
MODELAR CUBO-ESFERA
   ind: indice del modelo a usar
   r: radio de la esfera
   n: número de divisiones
   hrep: repetición horizontal de la textura
   vrep: repetición vertical de la textura
   
Nota: requiere el script scDistTriangulo
Autor: Clamud
*/
var r,n, hrep,vrep, X,Y,Z, i,j, d,
x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, u1,u2,v1,v2;

r = argument1; //radio
n = max( 1, floor(argument2) ); //n es un entero mayor o igual a 1
hrep = argument3; //repetición de la textura
vrep = argument4;

//Calcular los vectores normales (unitarios)
X[n,n] = 0; //inicializar arreglos
Y[n,n] = 0;
Z[n,n] = 0;
for( i=0; i<=n; i+=1 )
{
    for( j=0; j<=n; j+=1 )
    {
        x1 = 2*i/n - 1;
        y1 = 2*j/n - 1;
        z1 = 1;
        d = point_distance_3d( 0,0,0, x1,y1,z1 );
        X[i,j] = x1/d;
        Y[i,j] = y1/d;
        Z[i,j] = z1/d;
    }
}

//Construir el modelo
for( i=0; i<n; i+=1 )
{
    for( j=0; j<n; j+=1 )
    {
        x1=X[i,j]; x2=X[i+1,j]; x3=X[i+1,j+1]; x4=X[i,j+1];
        y1=Y[i,j]; y2=Y[i+1,j]; y3=Y[i+1,j+1]; y4=Y[i,j+1];
        z1=Z[i,j]; z2=Z[i+1,j]; z3=Z[i+1,j+1]; z4=Z[i,j+1];
       
        u1=i*hrep/n; u2=(i+1)*hrep/n;
        v1=j*vrep/n; v2=(j+1)*vrep/n;
       
        if( scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 ) > 0 ) //celda N
        {
            //z+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //z-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, -y4*r, -z4*r, x4,-y4,-z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, -y1*r, -z1*r, x1,-y1,-z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, -y3*r, -z3*r, x3,-y3,-z3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, -y2*r, -z2*r, x2,-y2,-z2, u2, v1 );
            d3d_model_primitive_end( argument0 );
           
            //y+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, z4*r, -y4*r, x4,z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, z1*r, -y1*r, x1,z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, z3*r, -y3*r, x3,z3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, z2*r, -y2*r, x2,z2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //y-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -x4*r, -z4*r, -y4*r, -x4,-z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -x1*r, -z1*r, -y1*r, -x1,-z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -x3*r, -z3*r, -y3*r, -x3,-z3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, -x2*r, -z2*r, -y2*r, -x2,-z2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
           
            //x+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, z4*r, -x4*r, -y4*r, z4,-x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, z1*r, -x1*r, -y1*r, z1,-x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, z3*r, -x3*r, -y3*r, z3,-x3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, z2*r, -x2*r, -y2*r, z2,-x2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //x-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -z4*r, x4*r, -y4*r, -z4,x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -z1*r, x1*r, -y1*r, -z1,x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -z3*r, x3*r, -y3*r, -z3,x3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, -z2*r, x2*r, -y2*r, -z2,x2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
        }
        else //celda Z
        {
            //z+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //z-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, -y1*r, -z1*r, x1,-y1,-z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, -y2*r, -z2*r, x2,-y2,-z2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, -y4*r, -z4*r, x4,-y4,-z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, -y3*r, -z3*r, x3,-y3,-z3, u2, v2 );
            d3d_model_primitive_end( argument0 );
           
            //y+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, z1*r, -y1*r, x1,z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, z2*r, -y2*r, x2,z2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, z4*r, -y4*r, x4,z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, z3*r, -y3*r, x3,z3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //y-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -x1*r, -z1*r, -y1*r, -x1,-z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -x2*r, -z2*r, -y2*r, -x2,-z2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, -x4*r, -z4*r, -y4*r, -x4,-z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -x3*r, -z3*r, -y3*r, -x3,-z3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
           
            //x+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, z1*r, -x1*r, -y1*r, z1,-x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, z2*r, -x2*r, -y2*r, z2,-x2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, z4*r, -x4*r, -y4*r, z4,-x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, z3*r, -x3*r, -y3*r, z3,-x3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //x-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -z1*r, x1*r, -y1*r, -z1,x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -z2*r, x2*r, -y2*r, -z2,x2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, -z4*r, x4*r, -y4*r, -z4,x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -z3*r, x3*r, -y3*r, -z3,x3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
        }
    }
}

scDomoEsferico1( ind, r, n, hrep, vrep );
Es el script en el que está basado el script anterior. El modelo corresponde a la cara de un cubo cuyo vector normal apunta en dirección z, se puede usar para formar una esfera con diferentes texturas; los argumentos son iguales a los anteriores.
Código
///scDomoEsferico1( ind, r, n, hrep, vrep );
/*
MODELAR DOMO ESFÉRICO (CUBO-ESFERA)
   ind: indice del modelo a usar
   r: radio de la esfera
   n: número de divisiones
   hrep: repetición horizontal de la textura
   vrep: repetición vertical de la textura
   
Nota: requiere el script scDistTriangulo
Autor: Clamud
*/
var r,n, hrep,vrep, X,Y,Z, i,j, d,
x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4;

r = argument1;
n = max( 1, floor(argument2) ); //n es un entero mayor o igual a 1
hrep = argument3; //repetición de la textura
vrep = argument4;

//Calcular los vectores normales
X[n,n] = 0; //inicializar arreglos
Y[n,n] = 0;
Z[n,n] = 0;
for( i=0; i<=n; i+=1 )
{
    for( j=0; j<=n; j+=1 )
    {
        x1 = 2*i/n - 1;
        y1 = 2*j/n - 1;
        z1 = 1;
        d = point_distance_3d( 0,0,0, x1,y1,z1 );
        X[i,j] = x1/d;
        Y[i,j] = y1/d;
        Z[i,j] = z1/d;
    }
}

//Construir el modelo
for( i=0; i<n; i+=1 )
{
    for( j=0; j<n; j+=1 )
    {
        x1=X[i,j]; x2=X[i+1,j]; x3=X[i+1,j+1]; x4=X[i,j+1];
        y1=Y[i,j]; y2=Y[i+1,j]; y3=Y[i+1,j+1]; y4=Y[i,j+1];
        z1=Z[i,j]; z2=Z[i+1,j]; z3=Z[i+1,j+1]; z4=Z[i,j+1];
       
        d3d_model_primitive_begin( argument0, pr_trianglestrip );
       
        if( scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 ) > 0 ) //celda N
        {
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4,  i*hrep/n,    (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1,  i*hrep/n,     j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, (i+1)*hrep/n, (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, (i+1)*hrep/n,  j*vrep/n );
        }
        else //celda Z
        {
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1,  i*hrep/n,     j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, (i+1)*hrep/n,  j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4,  i*hrep/n,    (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, (i+1)*hrep/n, (j+1)*vrep/n );
        }
        d3d_model_primitive_end( argument0 );
    }
}

scCuboEsfera2( ind, r, n, hrep, vrep );
Es casi igual a scCuboEsfera1, pero la forma en que se calculan los vértices del modelo es diferente, aquí se determinan los puntos de intersección de un conjunto de circunferencias máximas de la esfera, como resultado se tiene un modelo con una distribución de triángulos más uniforme.
Código
///scCuboEsfera2( ind, r, n, hrep, vrep );
/*
MODELAR CUBO-ESFERA
   ind: indice del modelo a usar
   r: radio de la esfera
   n: número de divisiones
   hrep: repetición horizontal de la textura
   vrep: repetición vertical de la textura
   
Nota: requiere el script scDistTriangulo
Autor: Clamud
*/
var r,n, hrep,vrep, X,Y,Z, i,j, d, alfa,beta,
x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, u1,u2,v1,v2;

r = argument1; //radio
n = max( 1, floor(argument2) ); //n es un entero mayor o igual a 1
hrep = argument3; //repetición de la textura
vrep = argument4;

//Calcular los vectores normales (unitarios)
X[n,n] = 0; //inicializar arreglos
Y[n,n] = 0;
Z[n,n] = 0;
for( i=0; i<=n; i+=1 )
{
    alfa = (i/n)*(pi/2)-(pi/4);
    for( j=0; j<=n; j+=1 )
    {
        beta = (j/n)*(pi/2)-(pi/4);
        x1 = sin(alfa);
        y1 = cos(alfa)*tan(beta);
        z1 = cos(alfa);
        d = point_distance_3d( 0,0,0, x1,y1,z1 );
        X[i,j] = x1/d;
        Y[i,j] = y1/d;
        Z[i,j] = z1/d;
    }
}

//Construir el modelo
for( i=0; i<n; i+=1 )
{
    for( j=0; j<n; j+=1 )
    {
        x1=X[i,j]; x2=X[i+1,j]; x3=X[i+1,j+1]; x4=X[i,j+1];
        y1=Y[i,j]; y2=Y[i+1,j]; y3=Y[i+1,j+1]; y4=Y[i,j+1];
        z1=Z[i,j]; z2=Z[i+1,j]; z3=Z[i+1,j+1]; z4=Z[i,j+1];
       
        u1=i*hrep/n; u2=(i+1)*hrep/n;
        v1=j*vrep/n; v2=(j+1)*vrep/n;
       
        if( scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 ) > 0 ) //celda N
        {
            //z+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //z-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, -y4*r, -z4*r, x4,-y4,-z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, -y1*r, -z1*r, x1,-y1,-z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, -y3*r, -z3*r, x3,-y3,-z3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, -y2*r, -z2*r, x2,-y2,-z2, u2, v1 );
            d3d_model_primitive_end( argument0 );
           
            //y+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x4*r, z4*r, -y4*r, x4,z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x1*r, z1*r, -y1*r, x1,z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x3*r, z3*r, -y3*r, x3,z3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, x2*r, z2*r, -y2*r, x2,z2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //y-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -x4*r, -z4*r, -y4*r, -x4,-z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -x1*r, -z1*r, -y1*r, -x1,-z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -x3*r, -z3*r, -y3*r, -x3,-z3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, -x2*r, -z2*r, -y2*r, -x2,-z2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
           
            //x+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, z4*r, -x4*r, -y4*r, z4,-x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, z1*r, -x1*r, -y1*r, z1,-x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, z3*r, -x3*r, -y3*r, z3,-x3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, z2*r, -x2*r, -y2*r, z2,-x2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
            //x-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -z4*r, x4*r, -y4*r, -z4,x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -z1*r, x1*r, -y1*r, -z1,x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -z3*r, x3*r, -y3*r, -z3,x3,-y3, u2, v2 );
            d3d_model_vertex_normal_texture( argument0, -z2*r, x2*r, -y2*r, -z2,x2,-y2, u2, v1 );
            d3d_model_primitive_end( argument0 );
        }
        else //celda Z
        {
            //z+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //z-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, -y1*r, -z1*r, x1,-y1,-z1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, -y2*r, -z2*r, x2,-y2,-z2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, -y4*r, -z4*r, x4,-y4,-z4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, -y3*r, -z3*r, x3,-y3,-z3, u2, v2 );
            d3d_model_primitive_end( argument0 );
           
            //y+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, x1*r, z1*r, -y1*r, x1,z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, x2*r, z2*r, -y2*r, x2,z2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, x4*r, z4*r, -y4*r, x4,z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, x3*r, z3*r, -y3*r, x3,z3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //y-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -x1*r, -z1*r, -y1*r, -x1,-z1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -x2*r, -z2*r, -y2*r, -x2,-z2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, -x4*r, -z4*r, -y4*r, -x4,-z4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -x3*r, -z3*r, -y3*r, -x3,-z3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
           
            //x+
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, z1*r, -x1*r, -y1*r, z1,-x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, z2*r, -x2*r, -y2*r, z2,-x2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, z4*r, -x4*r, -y4*r, z4,-x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, z3*r, -x3*r, -y3*r, z3,-x3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
            //x-
            d3d_model_primitive_begin( argument0, pr_trianglestrip );
            d3d_model_vertex_normal_texture( argument0, -z1*r, x1*r, -y1*r, -z1,x1,-y1, u1, v1 );
            d3d_model_vertex_normal_texture( argument0, -z2*r, x2*r, -y2*r, -z2,x2,-y2, u2, v1 );
            d3d_model_vertex_normal_texture( argument0, -z4*r, x4*r, -y4*r, -z4,x4,-y4, u1, v2 );
            d3d_model_vertex_normal_texture( argument0, -z3*r, x3*r, -y3*r, -z3,x3,-y3, u2, v2 );
            d3d_model_primitive_end( argument0 );
        }
    }
}

scDomoEsferico2( ind, r, n, hrep, vrep );
También modela un fragmento de esfera, usa el método del script anterior.
Código
///scDomoEsferico2( ind, r, n, hrep, vrep );
/*
MODELAR DOMO ESFÉRICO (CUBO-ESFERA)
   ind: indice del modelo a usar
   r: radio de la esfera
   n: número de divisiones
   hrep: repetición horizontal de la textura
   vrep: repetición vertical de la textura
   
Nota: requiere el script scDistTriangulo
Autor: Clamud
*/
var r,n, hrep,vrep, X,Y,Z, i,j, d, alfa,beta,
x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4;

r = argument1;
n = max( 1, floor(argument2) ); //n es un entero mayor o igual a 1
hrep = argument3; //repetición de la textura
vrep = argument4;

//Calcular los vectores normales
X[n,n] = 0; //inicializar arreglos
Y[n,n] = 0;
Z[n,n] = 0;
for( i=0; i<=n; i+=1 )
{
    alfa = (i/n)*(pi/2)-(pi/4);
    for( j=0; j<=n; j+=1 )
    {
        beta = (j/n)*(pi/2)-(pi/4);
        x1 = sin(alfa);
        y1 = cos(alfa)*tan(beta);
        z1 = cos(alfa);
        d = point_distance_3d( 0,0,0, x1,y1,z1 );
        X[i,j] = x1/d;
        Y[i,j] = y1/d;
        Z[i,j] = z1/d;
    }
}

//Construir el modelo
for( i=0; i<n; i+=1 )
{
    for( j=0; j<n; j+=1 )
    {
        x1=X[i,j]; x2=X[i+1,j]; x3=X[i+1,j+1]; x4=X[i,j+1];
        y1=Y[i,j]; y2=Y[i+1,j]; y3=Y[i+1,j+1]; y4=Y[i,j+1];
        z1=Z[i,j]; z2=Z[i+1,j]; z3=Z[i+1,j+1]; z4=Z[i,j+1];
       
        d3d_model_primitive_begin( argument0, pr_trianglestrip );
       
        if( scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 ) > 0 ) //celda N
        {
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4,  i*hrep/n,    (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1,  i*hrep/n,     j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, (i+1)*hrep/n, (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, (i+1)*hrep/n,  j*vrep/n );
        }
        else //celda Z
        {
            d3d_model_vertex_normal_texture( argument0, x1*r, y1*r, z1*r, x1,y1,z1,  i*hrep/n,     j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x2*r, y2*r, z2*r, x2,y2,z2, (i+1)*hrep/n,  j*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x4*r, y4*r, z4*r, x4,y4,z4,  i*hrep/n,    (j+1)*vrep/n );
            d3d_model_vertex_normal_texture( argument0, x3*r, y3*r, z3*r, x3,y3,z3, (i+1)*hrep/n, (j+1)*vrep/n );
        }
        d3d_model_primitive_end( argument0 );
    }
}

Los siguientes scripts se usan dentro de los anteriores.

scNormal( x1,y1,z1, x2,y2,z2, x3,y3,z3 );
Calcula el vector normal de un triángulo, para que el dodecaedro estrellado tenga una iluminación adecuada. Se podría optimizar para usar las nuevas características de los arreglos en :GMS:, lo dejaré así por ahora.
Código
///scNormal( x1,y1,z1, x2,y2,z2, x3,y3,z3 );
/*
CALCULAR VECTOR NORMAL
Se obtiene el vector normal a un triangulo con los
puntos indicados en orden de las manecillas del reloj.

Devuelve: nada, pero se asignan las variables nx, ny, nz.

Nota: el vector obtenido está invertido porque
el sistema de coordenadas en GM está invertido.
Autor: Clamud
*/
var Ax,Ay,Az, Bx,By,Bz, l;

//Vector A
Ax = argument3 - argument0;
Ay = argument4 - argument1;
Az = argument5 - argument2;

//Vector B
Bx = argument6 - argument0;
By = argument7 - argument1;
Bz = argument8 - argument2;

//n = A x B (producto cruz)
nx = (Ay * Bz) - (Az * By);
ny = (Az * Bx) - (Ax * Bz);
nz = (Ax * By) - (Ay * Bx);

//Unitario
l = point_distance_3d( 0,0,0, nx,ny,nz );
nx/=l;  ny/=l;  nz/=l;

scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 );
Calcula la distancia entre un punto y un plano definido con tres puntos, se usa para garantizar que la superficie de las esferas es completamente convexa.
Código
///scDistTriangulo( x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4 );
/*                  0  1  2   3  4  5   6  7  8   9  10 11
DISTANCIA A TRIANGULO
Se obtiene la distancia entre un punto (x0,y0,z0) y
un plano definido con tres puntos en sentido horario

Devuelve: un número real
Autor: Clamud
*/
var Ax,Ay,Az, Bx,By,Bz, Nx,Ny,Nz;

//Vector A
Ax = argument6 - argument3;
Ay = argument7 - argument4;
Az = argument8 - argument5;

//Vector B
Bx = argument9  - argument3;
By = argument10 - argument4;
Bz = argument11 - argument5;

//N = A x B (producto cruz)
Nx = (Ay * Bz) - (Az * By);
Ny = (Az * Bx) - (Ax * Bz);
Nz = (Ax * By) - (Ay * Bx);

//Unitario
//l = point_distance_3d( 0,0,0, Nx,Ny,Nz );
//Nx/=l;  Ny/=l;  Nz/=l;

//Distacia
return
(argument0-argument3)*Nx +
(argument1-argument4)*Ny +
(argument2-argument5)*Nz;

Es probable que esta lista crezca con el tiempo. Pueden solicitar otras figuras.

9
Preguntas y respuestas / Guardar matrices en cadenas de texto
« en: Mayo 20, 2015, 05:17:40 pm »
Estoy trabajando en un proyecto en el que uso muchos arreglos 2D, y esos arreglos tengo que guardarlos y cargarlos desde archivos externos.

Al principio, para simplificar el código, usaba ds_grids, y con la ayuda de las funciones ds_grid_write y ds_grid_read manejaba las matrices como una sola cadena de texto.

Después empecé a trabajar con ENIGMA y me dí cuenta de que el juego tenía un rendimiento mucho mayor, el problema es que las ds_grids creadas con GM no son compatibles con las de ENIGMA, entonces para que el juego fuese compatible con los dos ambientes de desarrollo, comencé a guardar los datos en archivos de texto usando las funciones file_text_write_real y file_text_read_real, esto funciona bien, pero no me gusta que los archivos quedan de un tamaño muy grande para la información que contienen, y además se pueden editar fácilmente con el block de notas.

Ahora he pensado en crear algunas funciones para guardar los datos de forma parecida a como lo hacen las funciones ds_grid, pero no tengo suficientes ideas o información para empezar. Sé que internamente GM maneja los números en tipos parecidos a los que se usan en C (bool, int, float, double), y cuando se inicializa una variable, ésta ocupa la menor cantidad de bytes necesarios para guardar la cantidad requerida, cuando el valor cambia también puede cambiar el tipo interno. También he notado que los números enteros con signo se representan usando el complemento a dos, pero no tengo idea de cómo se representan los números con punto flotante.

La forma de guardar también puede depender de la codificación del archivo de texto. Otra opción es guardar en archivos binarios.
Espero que alguien pueda ayudarme con información o ideas.
Gracias.

10
Preguntas y respuestas / Operadores que no aparecen en el manual
« en: Mayo 17, 2015, 04:27:58 pm »
Algunas veces he encontrado códigos que usan estos operadores:
<> //diferente a
:= //asignación, comparación
y según mis pruebas son equivalentes a estos:
!= //diferente a
=  //asignación, comparación
todos funcionan igual en :GM8: y :GMS: ¿Alguien sabe si tienen un comportamiento especial?

11
Preguntas y respuestas / Copiar código con colores [Solucionado]
« en: Diciembre 22, 2014, 05:09:02 pm »
Buen día, he estado buscando una forma sencilla (automática) para copiar los colores junto con el código GML, para pegarlo en algún editor de texto como Word. Yo uso  :GM8::GMS:, me gusta más la combinación de colores de GM8, quiero copiar esos colores. He leído que hay editores de código externos para GML, ¿en alguno de ellos se podrán copiar los colores?
Gracias, hasta luego.

12
Preguntas y respuestas / Cómo viajar de una room a varias rooms
« en: Noviembre 24, 2014, 08:56:02 pm »
Hola, buen día.

Quiero consultarlos para saber qué técnicas se pueden usar para pasar a una room determinada dependiendo de la salida que se tome en la room actual. Ejemplos: como lo que hacen las tuberías en Super Mario Bros. y las puertas en Metroid.

Lo que yo he hecho es poner objetos como salidas y en cada instancia he agregado un "Creation code" definiendo la room de destino y las coordenadas iniciales en la room de destino (porque algunas rooms tienen muchas entradas). Pero a veces es complicado hacer modificaciones a las rooms porque al cambiar la posición de una entrada hay que hacer varias modificaciones a las posciones de las salidas y a los creation codes de la room que conecta con la otra.

¿Qué métodos han usado? ¿cuáles me recomiendan?
Gracias.

13
General / ¿Cómo es el volumen de colisión de Mario 64?
« en: Noviembre 22, 2014, 05:17:19 pm »
Desde hace tiempo he estado buscando documentación relacionada con la programación o el diseño de Mario 64, pero no he encontrado algo muy extenso. He jugado observando cuidadosamente para tratar de descubrir por mi mismo sus secretos, pero la única conclusión a la que he llegado es que el volumen de colisión de Mario cambia dependiendo de la superficie. Tampoco tengo los conocimientos necesarios para descifrar el código fuente (si es que encuentro alguno).

¿Quién sabe dónde hay información sobre esto?
Gracias por su atención.

14
Preguntas y respuestas / Bugs en funciones file_text
« en: Noviembre 15, 2014, 06:56:07 am »
Saludos.

He estado trabajando en un método para guardar y cargar información a través de archivos de texto en GM81. Después de algunas pruebas descubrí unos bugs y algunos resultados poco predecibles en las funciones file_text_*, que no se explican en el manual:

  • La función file_text_write_real no escribe correctamente los números negativos (si no son enteros).
  • Dependiendo de la configuración regional de Windows, la función file_text_write_real escribe comas en vez de puntos como separador decimal y la función file_text_read_real no puede leerlos.
  • La función *write_real escribe un espacio y el número, pero la función *read_real no toma en cuenta los espacios, así que, en una sola línea, lee números con punto decimal separados por puntos.
  • La función *write_real siempre hace un redondeo a 6 cifras decimales.

Esas son las cosas que más me han retrasado, creo que hay otros detalles pero son menos importantes.

¿Alguien sabe dónde puedo encontrar información más detallada sobre esto, o conoce otras peculiaridades de las funciones file_text*?

Gracias por la ayuda.

15
Preguntas y respuestas / Clip plane
« en: Noviembre 10, 2014, 03:31:47 pm »
Hola comunidad.

Lo que voy a pedir es algo difícil pero tal vez me puedan dar algunas ideas para resolverlo. Lo que quiero hacer es un "clip plane" o "plano de recorte" en 3D.

El objetivo es hacer que sólo se dibujen los polígonos de un lado del plano. Una forma de hacer un clip plane es reducir el rango znear-zfar en la función d3d_set_projection_ext pero me gustaría que se pudiera hacer con un plano en un ángulo oblicuo a la proyección.

La aplicación que le quiero dar es hacer un espejo móvil en 3D. Ya tengo un espejo que funciona (usando surfaces), lo puedo mover y orientar, pero cuando hay objetos cercanos detrás del espejo aparecen en la imagen de reflejo, por eso quiero recortarlos.

Páginas: 1 2