• Welcome to Jose's Read Only Forum 2023.
 

Causing Chaos: Generating Planetary Terrains

Started by Charles Pegge, December 03, 2007, 06:38:37 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Charles Pegge

This is a snippet of code, which I use to generate a rocky asteroid. I am putting it here to show the technique before it gets too complex and obscured.

The key point is to generate a spherical mesh and use the coordinates to seed the randomiser, then to extract a random number and use that to perturb the coordinates and at the same time generate shading for the valleys.

This is ideal for use with recursively generated facets because all the irregular pieces must fit together!  Using the spherepoint vertex product to seed the RANDOMIZE function, ensures this happens.



SUB midquad (a AS vector3dv,b AS vector3dv , c AS vector3dv, d AS vector3dv, BYVAL s AS SINGLE , n AS vector3dv)
    s=s/3
    n.x=(a.x + b.x + c.x + d.x)*s
    n.y=(a.y + b.y + c.y + d.y)*s
    n.z=(a.z + b.z + c.z + d.z)*s
END SUB


SUB spherepoint(ab AS vector3dv)
    LOCAL p AS DOUBLE ' sphere point factor
    p=1/SQR(ab.x*ab.x + ab.y*ab.y + ab.z*ab.z)
    ' raise this vector to the sphere point
    ab.x=ab.x*p
    ab.y=ab.y*p
    ab.z=ab.z*p
END SUB



SUB perturb(m AS SINGLE,v AS vector3dv,c AS vector3dv,r AS vector3dv)
    RANDOMIZE v.x*11+v.y*12+v.z*13
    c.x=RND: r.x=v.x*(1+c.x*m)
    c.y=RND: r.y=v.y*(1+c.y*m)
    c.z=RND: r.z=v.z*(1+c.z*m)
END SUB



SUB geomid(a AS vector3dv, b AS vector3dv, ab AS vector3dv)
    LOCAL c AS vector3dv
    ab.x=(a.x + b.x)*0.5
    ab.y=(a.y + b.y)*0.5
    ab.z=(a.z + b.z)*0.5
    spherepoint ab
    perturb 0.05,ab,c,ab
END SUB


SUB chvertex3dv(v AS vector3dv)
    LOCAL c,r AS vector3dv
    LOCAL cc AS SINGLE
    perturb 0.03,v,c,r
    cc=(c.x+c.y+c.z)*0.333333
    glcolor3f cc,cc,cc ' shading without using normals
    glvertex3dv  r.x

END SUB

SUB quado(a AS vector3dv, b AS vector3dv , c AS vector3dv, d AS vector3dv, BYVAL r AS LONG)
    DECR r ' recursive
    IF r<0 THEN
        'plot triangle
        LOCAL n,m,v,w  AS vector3dv
        LOCAL nn,g AS SINGLE
        midquad a,b,d,c,4,n
        midquad a,b,d,c,1,m
        g=0.3
        'g=0
        nn=0.5
        glbegin GL_QUADS
        glnormal3dv n.x
        gltexcoord2f 0+RND*.5, .75-RND*0.2
        chvertex3dv a
        gltexcoord2f 0+RND*.4, .25+RND*0.1
        chvertex3dv b
        gltexcoord2f 1-RND*.2, .25+RND*0.15
        chvertex3dv d
        gltexcoord2f 1-RND*.3, .75-RND*.25
        chvertex3dv c
        glend
        EXIT SUB
    END IF
    LOCAL ab,bc,bd,ec,ca AS vector3dv
    geomid a,b,ab
    geomid b,c,bc
    geomid b,d,bd
    geomid d,c,ec
    geomid c,a,ca
    quado a,ab,ca,bc,r
    quado ab,b,bc,bd,r
    quado bc,bd,ec,d,r
    quado ca,bc,c,ec,r
END SUB


SUB quadosphere4(BYVAL n AS LONG) ' OCTAHEDRAL BASE
    'n=3 ' yields 8*4^n quad facets
    '
    LOCAL v1,v2,v3,v4,v5,v6 AS vector3dv
    'Octahedral coordinates
    v1.x=0 :v1.y=1 :v1.z=0
    v2.x=-1:v2.y=0 :v2.z=0
    v3.x=0 :v3.y=0 :v3.z=1
    v4.x=1 :v4.y=0 :v4.z=0
    v5.x=0 :v5.y=0 :v5.z=-1
    v6.x=0 :v6.y=-1:v6.z=0
    ' generate recursive diamond facets (paired triangles)
    ' NB: these diamond facets are not flat (coplanar)
    quado v1,v2,v3,v6,n
    quado v1,v3,v4,v6,n
    quado v1,v4,v5,v6,n
    quado v1,v5,v2,v6,n
END SUB

SUB quadosphere6(BYVAL n AS LONG) ' CUBIC BASE
    'n=3 ' yields 6*4^n quad facets
    '
    LOCAL v1,v2,v3,v4,v5,v6,v7,v8 AS vector3dv
    LOCAL s AS SINGLE
    s=1/SQR(3)
    'cube coordinates
    v1.x=-s : v1.y= s : v1.z= s
    v2.x=-s : v2.y=-s : v2.z= s
    v3.x= s : v3.y= s : v3.z= s
    v4.x= s : v4.y=-s : v4.z= s
    '--------------------------
    v5.x= s : v5.y= s : v5.z=-s
    v6.x= s : v6.y=-s : v6.z=-s
    v7.x=-s : v7.y= s : v7.z=-s
    v8.x=-s : v8.y=-s : v8.z=-s

    ' generate recursive diamond facets (paired triangles)
    ' NB: these diamond facets are not flat (coplanar)
    quado v1,v2,v3,v4,n
    quado v3,v4,v5,v6,n
    quado v5,v6,v7,v8,n
    quado v7,v8,v1,v2,n
    quado v1,v3,v7,v5,n
    quado v2,v4,v8,v6,n
END SUB


SUB quadosphere10(BYVAL n AS LONG) ' ICOSAHEDRAL BASE
    'n=3 ' yields 10*4^n quad facets
    '
    LOCAL v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12 AS vector3dv
    LOCAL a,s,c,p AS SINGLE
    a=ATN(2):s=SIN(a):c=COS(a):p=ATN(1)*8/5
    'icos vertex coordinates
    '--------------------------------------------------
    v1.x = 0            : v1.y= 1   : v1.z = 0
    v2.x = 0            : v2.y= c   : v2.z = s
    v3.x = SIN(p  )*s   : v3.y= c   : v3.z = COS(p  )*s
    v4.x = SIN(p*2)*s   : v4.y= c   : v4.z = COS(p*2)*s
    v5.x = SIN(p*3)*s   : v5.y= c   : v5.z = COS(p*3)*s
    v6.x = SIN(p*4)*s   : v6.y= c   : v6.z = COS(p*4)*s
    '--------------------------------------------------
    v7.x = SIN(p*0.5)*s : v7.y = -c : v7.z = COS(p*0.5)*s
    v8.x = SIN(p*1.5)*s : v8.y = -c : v8.z = COS(p*1.5)*s
    v9.x = SIN(p*2.5)*s : v9.y = -c : v9.z = COS(p*2.5)*s
    v10.x= SIN(p*3.5)*s : v10.y= -c : v10.z= COS(p*3.5)*s
    v11.x= SIN(p*4.5)*s : v11.y= -c : v11.z= COS(p*4.5)*s
    v12.x= 0            : v12.y= -1 : v12.z= 0
    '
    ' generate recursive diamond facets (paired triangles)
    ' NB: these diamond facets are not flat (coplanar)
    quado v1 ,v2 ,v3 ,v7 ,n
    quado v1 ,v3 ,v4 ,v8 ,n
    quado v1 ,v4 ,v5 ,v9 ,n
    quado v1 ,v5 ,v6 ,v10,n
    quado v1 ,v6 ,v2 ,v11,n
    '----------------------
    quado v12,v8 ,v7 ,v3 ,n
    quado v12,v9 ,v8 ,v4 ,n
    quado v12,v10,v9 ,v5 ,n
    quado v12,v11,v10,v6 ,n
    quado v12,v7 ,v11,v2 ,n
END SUB


SUB quadosphere(BYVAL n AS LONG)
    quadosphere10 n
END SUB
 



Petr Schreiber

Thanks Charles,

looks interesting.
What does "midquad" ( not included ) do ?


Thanks,
Petr

AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Charles Pegge


Oops! Sorry Petr, midquad simply calculates a midface normal. I have put it in at the top of the code.

I am building a library to hold these shapes, to be called geoometrica.inc.

This quadosphere is based on the octagon but the code can be used with cubes, icosahedra and 60 face polyhedra. - Anything that can be arranged in triangle pairs. These will give increasingly improved vertex distribution.

Kent Sarikaya

Getting into creations that can be generated by code is really cool stuff Charles. Especially when those creations could be huge amounts of data otherwise to attach.
Thanks for the code examples!

Charles Pegge

Adding CUBIC and ICOSAHEDRAL to the base geometries:
I've updated the code at the start of the thread, adding a PERTURB function.





SUB quadosphere6(BYVAL n AS LONG) ' CUBIC BASE
    'n=3 ' yields 6*4^n quad facets
    '
    LOCAL v1,v2,v3,v4,v5,v6,v7,v8 AS vector3dv
    LOCAL s AS SINGLE
    s=1/SQR(3)
    'cube coordinates
    v1.x=-s : v1.y= s : v1.z= s
    v2.x=-s : v2.y=-s : v2.z= s
    v3.x= s : v3.y= s : v3.z= s
    v4.x= s : v4.y=-s : v4.z= s
    '--------------------------
    v5.x= s : v5.y= s : v5.z=-s
    v6.x= s : v6.y=-s : v6.z=-s
    v7.x=-s : v7.y= s : v7.z=-s
    v8.x=-s : v8.y=-s : v8.z=-s

    ' generate recursive diamond facets (paired triangles)
    ' NB: these diamond facets are not flat (coplanar)
    quado v1,v2,v3,v4,n
    quado v3,v4,v5,v6,n
    quado v5,v6,v7,v8,n
    quado v7,v8,v1,v2,n
    quado v1,v3,v7,v5,n
    quado v2,v4,v8,v6,n
END SUB


SUB quadosphere10(BYVAL n AS LONG) ' ICOSAHEDRAL BASE
    'n=3 ' yields 10*4^n quad facets
    '
    LOCAL v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12 AS vector3dv
    LOCAL a,s,c,p AS SINGLE
    a=ATN(2):s=SIN(a):c=COS(a):p=ATN(1)*8/5
    'icos vertex coordinates
    '--------------------------------------------------
    v1.x = 0            : v1.y= 1   : v1.z = 0
    v2.x = 0            : v2.y= c   : v2.z = s
    v3.x = SIN(p  )*s   : v3.y= c   : v3.z = COS(p  )*s
    v4.x = SIN(p*2)*s   : v4.y= c   : v4.z = COS(p*2)*s
    v5.x = SIN(p*3)*s   : v5.y= c   : v5.z = COS(p*3)*s
    v6.x = SIN(p*4)*s   : v6.y= c   : v6.z = COS(p*4)*s
    '--------------------------------------------------
    v7.x = SIN(p*0.5)*s : v7.y = -c : v7.z = COS(p*0.5)*s
    v8.x = SIN(p*1.5)*s : v8.y = -c : v8.z = COS(p*1.5)*s
    v9.x = SIN(p*2.5)*s : v9.y = -c : v9.z = COS(p*2.5)*s
    v10.x= SIN(p*3.5)*s : v10.y= -c : v10.z= COS(p*3.5)*s
    v11.x= SIN(p*4.5)*s : v11.y= -c : v11.z= COS(p*4.5)*s
    v12.x= 0            : v12.y= -1 : v12.z= 0
    '
    ' generate recursive diamond facets (paired triangles)
    ' NB: these diamond facets are not flat (coplanar)
    quado v1 ,v2 ,v3 ,v7 ,n
    quado v1 ,v3 ,v4 ,v8 ,n
    quado v1 ,v4 ,v5 ,v9 ,n
    quado v1 ,v5 ,v6 ,v10,n
    quado v1 ,v6 ,v2 ,v11,n
    '----------------------
    quado v12,v8 ,v7 ,v3 ,n
    quado v12,v9 ,v8 ,v4 ,n
    quado v12,v10,v9 ,v5 ,n
    quado v12,v11,v10,v6 ,n
    quado v12,v7 ,v11,v2 ,n
END SUB


SUB quadosphere(BYVAL n AS LONG)
    quadosphere10 n
END SUB