Christmas Wreath

This started out as a series of Advent challenges a couple of Christmases ago, but is now open for anyone to post challenges on any topic!
DDRM

Christmas Wreath

Post by DDRM »

Time for a creative, open-ended one, I think! Write a program to draw a Christmas wreath. Anything you like! Intertwining lines for the wreath itself? Holly leaves? “3D” baubles? Your choice!

Please post your effort(s) here for the pleasure of everyone else!
Hated Moron

Re: Christmas Wreath

Post by Hated Moron »

DDRM wrote: Wed 15 Dec 2021, 08:41 Write a program to draw a Christmas wreath. Anything you like! Intertwining lines for the wreath itself? Holly leaves? “3D” baubles? Your choice!

Please post your effort(s) here for the pleasure of everyone else!
Here is my effort. To see it animated click here.

wreath.jpg
You do not have the required permissions to view the files attached to this post.
DDRM

Re: Christmas Wreath

Post by DDRM »

Thanks, Richard, that's charming, and way beyond what I was expecting!

D
Hated Moron

Re: Christmas Wreath

Post by Hated Moron »

DDRM wrote: Wed 06 Dec 2023, 08:42 Thanks, Richard, that's charming, and way beyond what I was expecting!
The code's quite short (and 95% of it is the standard 3D boilerplate):

Code: Select all

      REM Holly_Berry_and_Leaf model from turbosquid.com
      REM - MAY NOT BE REUSED WITHOUT BEING REPURCHASED!

      REM This program is compatible with BBCSDL and BB4W + WEBGLLIB library
      INSTALL @lib$+"webgllib"

      nObj% = 20
      DIM Object%(nObj%-1), nVert%(nObj%-1), vFormat%(nObj%-1), vSize%(nObj%-1)
      DIM Texture%(nObj%-1), Material%(nObj%-1), Pan(nObj%-1), Tilt(nObj%-1)
      DIM Roll(nObj%-1), Xpos(nObj%-1), Ypos(nObj%-1), Zpos(nObj%-1)
      DIM Xfinal(nObj%-1), Yfinal(nObj%-1), Zfinal(nObj%-1)
      DIM Pfinal(nObj%-1), Tfinal(nObj%-1), Rfinal(nObj%-1)

      nLights% = 3
      DIM Light{(nLights%-1)Type%, Diffuse{r%,g%,b%,a%}, Specular{r%,g%,b%,a%}, \
      \         Ambient{r%,g%,b%,a%}, Position{x%,y%,z%}, Direction{x%,y%,z%}, \
      \         Range%, Falloff%, Attenuation0%, Attenuation1%, Attenuation2%, \
      \         Theta%, Phi%}
      DIM Light%(nLights%-1)

      DIM Material{Diffuse{r%,g%,b%,a%}, Ambient{r%,g%,b%,a%}, \
      \            Specular{r%,g%,b%,a%}, Emissive{r%,g%,b%,a%}, Power%}

      REM Initialise holly sprigs to random positions and orientations:
      FOR I% = 0 TO nObj% - 1
        Xpos(I%) = 300 * RND(1) - 150
        Ypos(I%) = 300 * RND(1) - 150
        Zpos(I%) = 300 * RND(1) - 150
        Pan(I%) = 2 * PI * RND(1)
        Tilt(I%) = 2 * PI * RND(1)
        Roll(I%) = 2 * PI * RND(1)
      NEXT

      PRINT "Please wait..."
      *REFRESH OFF
      *REFRESH

      ON CLOSE PROCcleanup : QUIT
      ON ERROR PROCcleanup : IF ERR=17 CHAIN @lib$+"../examples/tools/touchide" ELSE MODE 3 : PRINT REPORT$ : END
      ON MOVE Resize% OR= (@msg% = 5) : RETURN

      Device% = 0
      Object% = 0
      Resize% = FALSE
      PROCinitrender

      REPEAT
        WAIT 1
        PROCanimate
      UNTIL FALSE
      END

      DEF PROCanimate
      LOCAL bgcolour%, viewangle, aspectratio, mindist, maxdist, cameraroll
      LOCAL camera(), lookat(), temp() : DIM camera(2), lookat(2), temp(nObj% - 1)

      lookat() = 0, 0, 0
      bgcolour% = &FFC0C0F0
      viewangle = RAD(40)
      aspectratio = @size.x%/@size.y%
      mindist = 3.0
      maxdist = 300.0
      cameraroll = TIME/1000
      camera() = 0, 150, 10
      temp() = Xfinal() - Xpos() : Xpos() += temp() * 0.01
      temp() = Yfinal() - Ypos() : Ypos() += temp() * 0.01
      temp() = Zfinal() - Zpos() : Zpos() += temp() * 0.01
      temp() = Pfinal() - Pan()  : Pan()  += temp() * 0.01
      temp() = Tfinal() - Tilt() : Tilt() += temp() * 0.01
      temp() = Rfinal() - Roll() : Roll() += temp() * 0.01
      PROC_render(Device%, bgcolour%, nLights%, Light%(), nObj%, Material%(), Texture%(), \
      \ Object%(), nVert%(), vFormat%(), vSize%(), Pan(), Tilt(), Roll(), Xpos(), Ypos(), Zpos(), \
      \ camera(), lookat(), viewangle, aspectratio, mindist, maxdist, cameraroll)

      IF Resize% Resize% = FALSE : PROCcleanup : PROCinitrender
      ENDPROC

      DEF PROCinitrender
      LOCAL I%, nvert%, vformat%, vsize%
      VDU 26
      IF POS REM SDL thread sync

      Device% = FN_initgl(@hwnd%, 0, 3)
      IF Device% = 0 ERROR 100, "Can't initialise 3D library"

      REM Load the 3D object:
      Object% = FN_load3d(Device%, @dir$+"holly.fvf", nvert%, vformat%, vsize%)
      IF Object% = 0 ERROR 100, "Can't load holly.fvf"
      Object%() = Object% : nVert%() = nvert% : vFormat%() = vformat% : vSize%() = vsize%

      REM Final positions and orientations:
      FOR I% = 0 TO 7
        Pfinal(I%) = 2*PI*I%/8 + (RND(1) - 0.5) * 0.1
        Xfinal(I%) = -22 * COS(-Pfinal(I%))
        Zfinal(I%) = -22 * SIN(-Pfinal(I%))
      NEXT
      FOR I% = 8 TO nObj% - 1
        Pfinal(I%) = 2*PI*(I% - 8 + 0.5)/(nObj% - 8) + (RND(1) - 0.5) * 0.1
        Xfinal(I%) = -35 * COS(-Pfinal(I%))
        Zfinal(I%) = -35 * SIN(-Pfinal(I%))
      NEXT
      Yfinal() = 0
      Pfinal() += PI/6
      Tfinal() = -0.85
      Rfinal() = 0.1

      REM Point-source lights:
      Light{(0)}.Type% = 1                : REM point source
      Light{(0)}.Diffuse.r% = FN_f4(0.5)  : REM diffuse colour RGB
      Light{(0)}.Diffuse.g% = FN_f4(0.5)
      Light{(0)}.Diffuse.b% = FN_f4(0.5)
      Light{(0)}.Diffuse.a% = FN_f4(1)
      Light{(0)}.Specular.r% = FN_f4(1.0) : REM specular colour RGB
      Light{(0)}.Specular.g% = FN_f4(1.0)
      Light{(0)}.Specular.b% = FN_f4(1.0)
      Light{(0)}.Position.x% = FN_f4(100) : REM position XYZ
      Light{(0)}.Position.y% = FN_f4(200)
      Light{(0)}.Position.z% = FN_f4(0)
      Light{(0)}.Range% = FN_f4(500)      : REM range
      Light{(0)}.Attenuation0% = FN_f4(1) : REM attenuation (constant)
      Light%(0) = Light{(0)} - PAGE + !340

      REM Second light at +120°:
      Light{(1)} = Light{(0)}
      Light{(1)}.Position.x% = FN_f4(100*COS(2*PI/3))
      Light{(1)}.Position.z% = FN_f4(100*SIN(2*PI/3))
      Light%(1) = Light{(1)} - PAGE + !340

      REM Third light at -120°:
      Light{(2)} = Light{(0)}
      Light{(2)}.Position.x% = FN_f4(100*COS(-2*PI/3))
      Light{(2)}.Position.z% = FN_f4(100*SIN(-2*PI/3))
      Light%(2) = Light{(2)} - PAGE + !340

      REM Material to add specular reflection:
      Material.Diffuse.r% = FN_f4(1.0)
      Material.Diffuse.g% = FN_f4(1.0)
      Material.Diffuse.b% = FN_f4(1.0)
      Material.Specular.r% = FN_f4(.7)
      Material.Specular.g% = FN_f4(.7)
      Material.Specular.b% = FN_f4(.7)
      Material.Power% = FN_f4(20.0)
      Material%() = Material{} - PAGE + !340

      ENDPROC

      DEF PROCcleanup
      Object% += 0 : IF Object% PROC_release(Object%) : Object% = 0
      Device% += 0 : IF Device% PROC_release(Device%) : Device% = 0
      *REFRESH ON
      ENDPROC
Hated Moron

Re: Christmas Wreath

Post by Hated Moron »

Hated Moron wrote: Wed 06 Dec 2023, 09:59 The code's quite short (and 95% of it is the standard 3D boilerplate):
The 3D model was very cheap too (in fact I think it was on sale at the time and even cheaper than the $2 it is now).