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.
[spoiler=Código][gml]
///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 = 0;      v4[i1] = k*b;  v4[i2] = j*c;
        v5 = 0;      v5[i1] =-k*b;  v5[i2] = j*c;
        v2 = j*k*a;  v2[i1] = k*a;  v2[i2] = j*a;
        v3 = j*k*a;  v3[i1] =-k*a;  v3[i2] = j*a;
        v1 = j*k*c;  v1[i1] = 0;    v1[i2] = j*b;
         n = 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 );
    }
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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 = 0;      v4[i1] = k*b;  v4[i2] = j*c;
        v5 = 0;      v5[i1] =-k*b;  v5[i2] = j*c;
        v2 = j*k*a;  v2[i1] = k*a;  v2[i2] = j*a;
        v3 = j*k*a;  v3[i1] =-k*a;  v3[i2] = j*a;
        v1 = j*k*c;  v1[i1] = 0;    v1[i2] = j*b;
        v0 = 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 );
    }
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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;
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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 );
        }
    }
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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 );
    }
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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 );
        }
    }
}
[/gml][/spoiler]

scDomoEsferico2( ind, r, n, hrep, vrep );
También modela un fragmento de esfera, usa el método del script anterior.
[spoiler=Código][gml]
///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 );
    }
}
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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;
[/gml][/spoiler]

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.
[spoiler=Código][gml]
///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;
[/gml][/spoiler]

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