Jose's Read Only Forum 2023

IT-Consultant: Charles Pegge => OxygenBasic Examples => Topic started by: Charles Pegge on December 03, 2007, 06:38:37 AM

Title: Causing Chaos: Generating Planetary Terrains
Post by: Charles Pegge on December 03, 2007, 06:38:37 AM
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
 


Title: Re: Causing Chaos: Generating Planetary Terrains
Post by: Petr Schreiber on December 03, 2007, 02:23:11 PM
Thanks Charles,

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


Thanks,
Petr

Title: Re: Causing Chaos: Generating Planetary Terrains
Post by: Charles Pegge on December 03, 2007, 04:58:13 PM

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.
Title: Re: Causing Chaos: Generating Planetary Terrains
Post by: Kent Sarikaya on December 03, 2007, 05:21:10 PM
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!
Title: Re: Causing Chaos: Generating Planetary Terrains
Post by: Charles Pegge on December 04, 2007, 12:03:12 AM
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