BBC BASIC for Windows
« The 3D editor tool kit: ideas »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 9:54pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: The 3D editor tool kit: ideas  (Read 426 times)
michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
xx The 3D editor tool kit: ideas
« Thread started on: Sep 11th, 2017, 7:23pm »

There are buttons and images showing the directional controls for a whole triangle or corner. I tested the interface for some of the tools already on the 3D render and it will work very nicely.

This is only the tool kit that is going to be adapted to the renderer.

*** If you feel a special tool should be added let me know. I will be adding a tool to rotate the image as you edit it and I also will add the ability to switch between triangles.

NOTE: Every time a move is made the image changes in the file..

I will start with 12 triangles so a person can make a decent 3D piece for their collection.

Use the left mouse button to try out the controls and watch the white box to see the label it has.

I will add keyboard controls WSAD and arrow controls later

Code:
      PROCgraphics(1100,400):REM this is not the final size
      res$=""
      res=0
      ls= 0
      LET rs= 24
      counl%=290
      counr%=2110
      REM setup buttons before use
      REM             x , y ,size,"fillcolor","command"
      res$=FNabutton(100,100,25,"light green","fill"):REM keeping it efficient
      res$=FNabutton(125,130,25,"yellow","fill")
      res$=FNabutton(300,100,25,"red","fill")
      res$=FNabutton(300,130,25,"cyan","fill")
      res$=FNabutton(500,100,25,"200,200,190","fill")
      res$=FNabutton(470,100,25,"200,190,200","fill")
      res$=FNabutton(593,70,75,"000,000,000","fill")  :REM select entire triangle
      res$=FNabutton(770,90,25,"100,50,100","fill") :REM LL triangle only
      res$=FNabutton(905,90,25,"50,100,50","fill"):REM LR triangle only
      res$=FNabutton(835,205,25,"200,50,100","fill"):REM TOP triangle only
      PROCcolor("f","white")
      LINE165,165,200,200:LINE200,200,180,200:LINE 200,200,200,180
      LINE 90,90,60,60:LINE 60,60,80,60:LINE 60,60,60,80
      LINE 315,170,315,200:LINE 315,200,300,180:LINE 315,200,330,180
      LINE 315,85,315,50:LINE 315,50,300,70:LINE 315,50,330,70
      LINE 460,115,430,115:LINE 430,115,440,130:LINE 430,115,440,100:LINE 535,115,560,115
      LINE 560,115,550,130:LINE 560,115,550,100:LINE 600,100,660,100:LINE 660,100,630,130
      LINE 630,130,600,100: LINE 800,100,900,100:LINE 900,100,850,200:LINE 850,200,800,100
      PROCcolor("f","black")
      REM TRACKING STARTS HERE
      REPEAT
        res$=""
        IF FNabutton(100,100,25,"green","out")="out" THEN res$="out"
        IF FNabutton(125,130,25,"blue","in")="in" THEN res$="in"
        IF FNabutton(300,100,25,"red","down")="down" THEN res$="down"
        IF FNabutton(300,130,25,"orange","up")="up" THEN res$="up"
        IF FNabutton(500,100,25,"purple","right")="right" THEN res$="right"
        IF FNabutton(470,100,25,"200,190,200","left")="left" THEN res$="left"
        IF FNabutton(593,70,75,"000,000,000","all")="all" THEN res$="all"
        IF FNabutton(770,90,25,"100,50,100","LL")="LL" THEN res$="LL" :REM LL triangle only
        IF FNabutton(905,90,25,"50,100,50","LR")="LR" THEN res$="LR":REM LR triangle only
        IF FNabutton(835,205,25,"200,50,100","TOP")="TOP" THEN res$="TOP":REM TOP triangle only
        PROCsbox(250,700,2150,600,"15")
        MOVE 260,650:PRINT res$
        WAIT 10
      UNTIL FALSE
      END
      REM x,y is lower left and c$=fillcolor:com$-command
      DEFFNabutton(x,y,size%,c$,com$)
      MOUSE mx,my,mb
      LOCAL ret$
      PROCcolor("f","5")
      PROCrect(x,y,x+size%,y+size%)
      IF com$="fill" THEN
        PROCpaint(x+5,y+5,c$)
      ENDIF
      IF mx>x AND mx<x+size% AND my>y AND my<y+size% THEN
        PROCcolor("f","15"):PROCrect(x,y,x+size%,y+size%)
        IF mb=4 THEN ret$=com$
      ENDIF
      =ret$
      DEFPROCarrowu(x,y)
      PRIVATE xx,yy
      PROCcolor("f","black")
      LINE xx,yy,xx-20,yy-20
      LINE xx,yy,xx+20,yy-20
      PROCcolor("f","15")
      LINE x,y,x-20,y-20
      LINE x,y,x+20,y-20
      xx=x:yy=y
      ENDPROC
      DEFPROCarrowd(x,y)
      PRIVATE hh,vv
      PROCcolor("f","000,000,000")
      LINE hh,vv,hh-20,vv+20
      LINE hh,vv,hh+20,vv+20
      PROCcolor("f","15")
      LINE x,y,x-20,y+20
      LINE x,y,x+20,y+20
      hh=x:vv=y
      ENDPROC
      REM  GRAPHICS(x,y)
      DEF PROCgraphics(x,y)
      VDU 23,22,x;y;8,15,16,1
      OFF
      VDU 5
      ENDPROC
      REM SBOX **********************
      DEF PROCsbox(x%,y%,w%,h%,c$)
      LOCAL ry%,sx%,sy%
      sx%=x%:sy%=y%
      IF x%>w% THEN x%=w%:w%=sx%
      IF y%>h% THEN y%=h%:h%=sy%
      ry%=y%
      PROCcolor("f",c$)
      REPEAT
        LINE x%,y%,w%,y%
        y%=y%+1
      UNTIL y%=h%
      y%=ry%
      IF c$<>"0" THEN PROCcolor("f","000,000,000") ELSE PROCcolor("f","white")
      LINE x%+2,y%+2,w%-2,y%+2
      LINE w%-2,y%+2,w%-2,h%-4
      LINE w%-2,h%-4,x%+2,h%-4
      LINE x%+2,h%-4,x%+2,y%+2
      PROCresetrgb
      ENDPROC
      REM RECT **********************
      DEFPROCrect(x%,y%,w%,h%)
      LOCAL sx%,sy%
      sx%=x%:sy%=y%
      IF x%>w% THEN x%=w%:w%=sx%
      IF y%>h% THEN y%=h%:h%=sy%
      LINE x%,y%,w%,y%
      LINE w%,y%,w%,h%
      LINE w%,h%,x%,h%
      LINE x%,h%,x%,y%
      ENDPROC
      REM pixel *******************
      DEFPROCpixel(x%,y%,c$)
      PROCcolor("f",c$)
      MOVE x%,y%:DRAW x%,y%
      ENDPROC
      REM SET  c$ can be colors like blue or 1 or a R,G,B color
      DEF PROCset(x%,y%,c$)
      LOCAL h%
      PROCcolor("f",c$)
      FOR h%=0 TO 20
        LINE x%+h%,y%,x%+h%,y%+20
      NEXT
      MOVE 0,0
      ENDPROC
      DEFPROCpaint(x%,y%,co$)
      PROCcolor("b","0"):PROCcolor("f",co$)
      FILL x%,y%
      ENDPROC
      REM restore default color palettes
      DEFPROCresetrgb
      COLOUR 0,0,0,0 :COLOUR 1,200,0,0 :COLOUR 2,000,200,000
      COLOUR 3,200,200,000:COLOUR 4,000,000,200:COLOUR 5,200,000,200
      COLOUR 6,000,200,200:COLOUR 7,200,200,200:COLOUR 8,056,056,056
      COLOUR 9,248,056,056:COLOUR 10,056,248,056:COLOUR 11,248,248,056
      COLOUR 12,056,056,248:COLOUR 13,248,056,248:COLOUR 14,056,248,248
      COLOUR 15,248,248,248
      ENDPROC
      DEF PROCcolor(fb$,rgb$)
      PRIVATE assemble$,br%,bg%,bb%
      IF rgb$="0" OR rgb$="black" THEN rgb$="000,000,000"
      IF rgb$="1" OR rgb$="red" THEN rgb$="200,000,000"
      IF rgb$="2" OR rgb$="green" THEN rgb$="000,200,000"
      IF rgb$="3" OR rgb$="yellow" THEN rgb$="200,200,000"
      IF rgb$="4" OR rgb$="blue" THEN rgb$="000,000,200"
      IF rgb$="5" OR rgb$="magenta" THEN rgb$="200,000,200"
      IF rgb$="6" OR rgb$="cyan" THEN rgb$="000,200,200"
      IF rgb$="7" OR rgb$="white" THEN rgb$="200,200,200"
      IF rgb$="8" OR rgb$="grey" THEN rgb$="056,056,056"
      IF rgb$="9" OR rgb$="light red" THEN rgb$="248,056,056"
      IF rgb$="10" OR rgb$="light green" THEN rgb$="056,248,056"
      IF rgb$="11" OR rgb$="light yellow" THEN rgb$="248,248,056"
      IF rgb$="12" OR rgb$="light blue" THEN rgb$="056,056,248"
      IF rgb$="13" OR rgb$="light magenta" THEN rgb$="248,056,248"
      IF rgb$="14" OR rgb$="light cyan" THEN rgb$="056,248,248"
      IF rgb$="15" OR rgb$="light white" THEN rgb$="248,248,248"
      assemble$=rgb$
      br%=VAL(MID$(assemble$,1,3)):bg%=VAL(MID$(assemble$,5,3)):bb%=VAL(MID$(assemble$,9,3))
      IF fb$="f" OR fb$="F" THEN COLOUR 0,br%,bg%,bb% : GCOL 0
      IF fb$="b" OR fb$="B" THEN COLOUR 1,br%,bg%,bb% : GCOL 128+1
      ENDPROC
      a      REM buttonz
      DEFFNbuttonz(X,Y,msg$)
      LOCAL initialx%,fi%,reduction%,tx,ty,mx%,my%,mb%,ad%,ady%,c$
      PRIVATE st$
      IF msg$<> "clearitall" THEN
        initialx%=LEN(msg$)
        LET tx= X+initialx%+25
        LET ty= Y:reduction%=0
        reduction%=initialx%/2
        reduction%=reduction%*6
        IF initialx%<20 THEN reduction%=reduction%/2
        initialx%=initialx%*22-reduction%
        MOUSE mx%,my%,mb%
        ad%=initialx%+8:ad%+=X:ady%=Y-28
        IF mx% >X AND mx%<ad% AND my%<Y+8 AND my%>ady% THEN
          c$="255,255,255"
          IF mb%=4 THEN st$=msg$
        ELSE c$="200,200,200"
        ENDIF
        IF FNrgb(X,Y)="000,000,000" THEN c$="200,200,200"
        PROCcolor("f",c$)
        IF FNrgb(X,Y)<>c$ THEN
          FOR fi%=12 TO 48
            LINE X-3,Y+20-fi%,X+initialx%+8,Y+20-fi%
          NEXT
          PROCcolor("f","000,000,000")
          MOVE tx,ty
          PRINT msg$
        ENDIF
      ENDIF
      IF msg$="clearitall" THEN st$=""
      =st$
 
« Last Edit: Sep 11th, 2017, 7:25pm by michael » User IP Logged

I like making program generators and like reinventing the wheel
DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #1 on: Sep 12th, 2017, 08:16am »

Hi Michael,

I think the hardest thing about D3D is making the models. I'm currently working on making some "primitives" - cylinder, sphere, box, etc - probably with variants that make only part of it. I'm incorporating the ability to rotate and shift the object in 3D, so it should be possible to generate a more complex object by combining the primitives. I'll include the option to generate surface normals and texture coordinates.

It would be great to have a way to edit single vertices of the objects, or to move them about relative to each other visually - I don't know if Ric is interested in adapting the great work he's done within his own system?

Best wishes,

D
User IP Logged

michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
xx Re: The 3D editor tool kit: ideas
« Reply #2 on: Sep 13th, 2017, 12:42am »

Thankfully, I had just figured out how to get a nice cycle with updates of any changes to the 3D image info.. Now I can merge the two programs together as I had tested and set up a turn based editor. The cycles and WAITs would allow the user to see the render and modify each triangle instantly with the program above.


I would love to try out your version and help create objects.

I will finish my version also, since I know this should work well.

The above program will be adapted to this one and I will make 12 triangles to edit.

Here is the successful cycle of the renderer.. This is so exciting !!

Code:
      IF INKEY$(-256)="W" INSTALL @lib$+"D3DLIBA" ELSE INSTALL @lib$+"OGLLIB"
      PROCcreate3d
      MODE 8
      DIM l%(0), b%(1), n%(1), f%(1), s%(1), m%(1), t%(1), y(1), p(1), r(1), X(1), Y(1), Z(1), e(2), a(2)
      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END
      IF INKEY$(-256)="W" d% = FN_initd3d(@hwnd%, 1, 0) ELSE d% = FN_initgl(@hwnd%, 1, 0)
      IF d% = 0 ERROR 100, "Can't initialise Direct3D"
      e() = 0, 0, -6
      a() = 0, 0, 0
      l%()=1
      REPEAT
        b%(0) = FN_load3d(d%, @dir$+"TRIANGLE.B3D", n%(0), f%(0), s%(0))
        IF b%(0) = 0 ERROR 100, "Can't load TRIANGLE.B3D"
        REM  t%(1) = FN_loadtexture(d%, @dir$+"purple.JPG")
        REM  IF t%(1) = 0 ERROR 100, "Can't load face.JPG"
  
  
        y() +=.01:REM yaw (rotations around the Y axis)
        REM pitch
        p() =0:REM TIME/100 (pitch angles rotations around the X axis)
        REM roll
        r() = 0:REM TIME/40 (roll angles (rotations around the Z axis)
        REM X (right left)
        X() = 0:REM SIN(TIME/200)
        REM Y() up and down
        Y() = 0
        REM Z() depth
        Z() =  10:REM
  
        REM PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
        PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000, 0) :REM experimental
        REM          1     2       3   4    5   6     7     8     9     10    11   yaw pitch roll X    Y    Z eye0123  18   19   20   ^mcd  ^( cam to farplane dist)
        REM 1 Val returned from FN_init3D
        REM 2 back color   3 #of lights   4 light pointers
        REM t%() - holds texture
        REM mcd - minimum near cam distance
  
  WAIT 1
      UNTIL FALSE
      END

      DEF PROCcleanup
      t%(1) += 0:IF t%(1) PROC_release(t%(1))
      b%(0) += 0:IF b%(0) PROC_release(b%(0))
      b%(1) += 0:IF b%(1) PROC_release(b%(1))
      d% += 0   :IF d%    PROC_release(d%)
      ENDPROC
      DEF PROCcreate3d
      F% = OPENOUT"TRIANGLE.B3D"
      PROC4(6):REM 3 vertices
      PROC4(&100042):REM vertex size &10 and format &42
      REM       LL x            LL y            LL z
      PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF)
      REM       LR x            LR y            LR z
      PROC4(FN_f4(1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF00FF00)
      REM     PEAK X     PEAK Y             PEAK Z
      PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FFFF0000)

      PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF0000FF)
      REM       LR x            LR y            LR z
      PROC4(FN_f4(-1)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FF00FF00)
      REM     PEAK X     PEAK Y             PEAK Z
      PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF):REM PROC4(&FFFF0000)

      CLOSE #F%
      ENDPROC
      DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC
 
« Last Edit: Sep 13th, 2017, 12:50am by michael » User IP Logged

I like making program generators and like reinventing the wheel
DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #3 on: Sep 14th, 2017, 1:39pm »

Here's my first function, to draw a cylinder, and some supporting functions. It's still a bit up in the air how to handle things, but it works OK.
The cylinder needs its normals facing out from the centre, so I've calculated them as the ends of the vector, which can then be moved/rotated/scaled with the vector data, but then it needs converting into proper normals before writing to the file. A bit ugly, but convenient, since my plan is to be able to fit several shapes together, and render it all as one file.
For shapes with flat faces,all the normals can be calculated at the end, which will be easier, but spheres will also need this approach.
One question to think about is where to put the centre of each shape. Logically it should be the centre (!), but here I've chosen the end, to make positioning of it (especially after scaling) more intuitive. That may or may not be the right answer. Any thoughts?

Best wishes,

D
Code:
           capped%=TRUE   :REM Include ends on the cylinder
      nf%=20         :Number of faces
      startface%=1   :Include the whole cylinder, or only part of it?
      endface%=nf%
      IF capped% THEN vpf%=12 ELSE vpf%=6   :REM each face has 2 triangles (6 vertices), +/- 2 more to form the caps
      nv%=vpf%*(endface%-startface%+1)      :REM number of vertices in the shape (needed to DIM arrays)
      REM Coordinates to map a texture to the shape. You might want to use only a small part of a texture
      texminu=0
      texmaxu=1
      texminv=0
      texmaxv=1

      DIM v(nv%,2),vn(nv%,2),t(nv%,1)  :REM hold vertex, normal, and texture data
      DIM vr(nv%,2),vnr(nv%,2)         :REM These are only needed for the display routine

      numverts%=FNMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
      PROCDisplay(v(),nv%)           :REM Wireframe display, really for diagnostic purposes
      vn()=vn()-v()                  :"Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
      PROCNormalise(nv%,vn())

      PROCWriteB3D("cylinder",nv%,&152,v(),vn(),t())   :REM File name, number of vertices, required vertex format, and arrays of vertex,normal, and texture data
      PRINT "managed to finish"
      END
      :
      DEFFNMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
      LOCAL a,pa,vpf%,nv%,l,r,tdu,tdv
      IF capped% THEN vpf%=12 ELSE vpf%=6
      nv%=vpf%*(endface%-startface%+1)
      REM Cylinder lies along X axis, and has centre of left hand end at 0,0,0
      REM Initially scale cylinder to 1 long, and radius 1. We can change this later!
      l=1
      r=1.0
      tdu=texmaxu-texminu
      tdv=texmaxv-texminv
      FOR a=0 TO endface%-startface%
        REM Calculate positions of vertices
        pa=a+startface%-1
        py=r*SIN(pa*2*PI/nf%)
        pz=r*COS(pa*2*PI/nf%)
        py2=r*SIN((pa+1)*2*PI/nf%)
        pz2=r*COS((pa+1)*2*PI/nf%)
        REM Fill vertex data
        v(a*vpf%,0)=0
        v(a*vpf%,1)=py
        v(a*vpf%,2)=pz
        v(a*vpf%+1,0)=l
        v(a*vpf%+1,1)=py2
        v(a*vpf%+1,2)=pz2
        v(a*vpf%+2,0)=l
        v(a*vpf%+2,1)=py
        v(a*vpf%+2,2)=pz
        v(a*vpf%+3,0)=0
        v(a*vpf%+3,1)=py
        v(a*vpf%+3,2)=pz
        v(a*vpf%+4,0)=0
        v(a*vpf%+4,1)=py2
        v(a*vpf%+4,2)=pz2
        v(a*vpf%+5,0)=l
        v(a*vpf%+5,1)=py2
        v(a*vpf%+5,2)=pz2
        REM Here are normals
        ny=(r+1)*SIN(pa*2*PI/nf%)
        nz=(r+1)*COS(pa*2*PI/nf%)
        ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
        nz2=(r+1)*COS((pa+1)*2*PI/nf%)
        vn(a*vpf%,0)=0
        vn(a*vpf%,1)=ny
        vn(a*vpf%,2)=nz
        vn(a*vpf%+1,0)=l
        vn(a*vpf%+1,1)=ny2
        vn(a*vpf%+1,2)=nz2
        vn(a*vpf%+2,0)=l
        vn(a*vpf%+2,1)=ny
        vn(a*vpf%+2,2)=nz
        vn(a*vpf%+3,0)=0
        vn(a*vpf%+3,1)=ny
        vn(a*vpf%+3,2)=nz
        vn(a*vpf%+4,0)=0
        vn(a*vpf%+4,1)=ny2
        vn(a*vpf%+4,2)=nz2
        vn(a*vpf%+5,0)=l
        vn(a*vpf%+5,1)=ny2
        vn(a*vpf%+5,2)=nz2
        REM Here are the texture mapping coordinates
        t(a*vpf%,0)=texminu
        t(a*vpf%,1)=texminv+tdv*pa/nf%
  
        t(a*vpf%+1,0)=texmaxu
        t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
  
        t(a*vpf%+2,0)=texmaxu
        t(a*vpf%+2,1)=texminv+tdv*pa/nf%
  
        t(a*vpf%+3,0)=texminu
        t(a*vpf%+3,1)=texminv+tdv*pa/nf%
  
        t(a*vpf%+4,0)=texminu
        t(a*vpf%+4,1)=texminv+tdv*(pa+1)/nf%
  
        t(a*vpf%+5,0)=texmaxu
        t(a*vpf%+5,1)=texminv+tdv*(pa+1)/nf%
  
        REM And now for the ends!  Vertices first
        IF capped% THEN
          v(a*vpf%+6,0)=0
          v(a*vpf%+6,1)=py
          v(a*vpf%+6,2)=pz
          v(a*vpf%+7,0)=0
          v(a*vpf%+7,1)=0
          v(a*vpf%+7,2)=0
          v(a*vpf%+8,0)=0
          v(a*vpf%+8,1)=py2
          v(a*vpf%+8,2)=pz2
    
          v(a*vpf%+9,0)=l
          v(a*vpf%+9,1)=py
          v(a*vpf%+9,2)=pz
          v(a*vpf%+10,0)=l
          v(a*vpf%+10,1)=0
          v(a*vpf%+10,2)=0
          v(a*vpf%+11,0)=l
          v(a*vpf%+11,1)=py2
          v(a*vpf%+11,2)=pz2
    
          REM And the normals:
          vn(a*vpf%+6,0)=-10
          vn(a*vpf%+6,1)=py
          vn(a*vpf%+6,2)=pz
          vn(a*vpf%+7,0)=-10
          vn(a*vpf%+7,1)=0
          vn(a*vpf%+7,2)=0
          vn(a*vpf%+8,0)=-10
          vn(a*vpf%+8,1)=py2
          vn(a*vpf%+8,2)=pz2
    
          vn(a*vpf%+9,0)=l+10
          vn(a*vpf%+9,1)=py
          vn(a*vpf%+9,2)=pz
          vn(a*vpf%+10,0)=l+10
          vn(a*vpf%+10,1)=0
          vn(a*vpf%+10,2)=0
          vn(a*vpf%+11,0)=l+10
          vn(a*vpf%+11,1)=py2
          vn(a*vpf%+11,2)=pz2
          REM And for the texture - rather arbitrary choice!
          t(a*vpf%+6,0)=texminu+tdu*a/nf%
          t(a*vpf%+6,1)=texminv
    
          t(a*vpf%+7,0)=texminu+tdu/2
          t(a*vpf%+7,1)=texmaxv
    
          t(a*vpf%+8,0)=texminu+tdu*(a+1)/nf%
          t(a*vpf%+8,1)=texminv
    
          t(a*vpf%+9,0)=texminu+tdu*a/nf%
          t(a*vpf%+9,1)=texminv
    
          t(a*vpf%+10,0)=texminu+tdu/2
          t(a*vpf%+10,1)=texmaxv
    
          t(a*vpf%+11,0)=texminu+tdu*(a+1)/nf%
          t(a*vpf%+11,1)=texminv
        ENDIF
      NEXT a
      PRINT nv%
      =nv%
      :
      DEFPROCRotate(a(),xa,ya,za)
      LOCAL xrm(),yrm(),zrm()
      DIM xrm(2,2),yrm(2,2),zrm(2,2)
      xrm()=1,0,0,0,COS(xa),-SIN(xa),0,SIN(xa),COS(xa)
      yrm()=COS(ya),0,SIN(ya),0,1,0,-SIN(ya),0,COS(ya)
      zrm()=COS(za),-SIN(za),0,SIN(za),COS(za),0,0,0,1
      REM Rotate around X axis, then Y, then Z. This matters! I find this the easiest order to visualise
      xrm()=xrm().yrm()
      xrm()=xrm().zrm()
      a()=a().xrm()
      ENDPROC
      :
      DEFPROCShift(a(),dx,dy,dz,nv%)
      LOCAL x%
      FOR x%=0 TO nv%-1
        a(x%,0)+=dx
        a(x%,1)+=dy
        a(x%,2)+=dz
      NEXT x%
      ENDPROC
      :
      DEFPROCDisplay(v(),nv%)
      LOCAL x%,xoff,yoff,zoff,xr,yr,zr
      xoff=1000
      yoff=700
      zoff=0
      xr=0
      yr=0
      zr=0
      *REFRESH OFF
      FOR zr=0 TO 2*PI STEP 0.1
        yr=zr/2
        xr=zr/3
        vr()=v()
        vr()*=100
        PROCRotate(vr(),xr,yr,zr)
        PROCShift(vr(),xoff,yoff,0,nv%)
  
        FOR x%=0 TO nv%-2 STEP 3
          MOVE vr(x%,0),vr(x%,1)
          DRAW vr(x%+1,0),vr(x%+1,1)
          DRAW vr(x%+2,0),vr(x%+2,1)
        NEXT x%
        *REFRESH
        WAIT 5
        CLS
      NEXT zr
      *REFRESH ON
      ENDPROC
      :
      DEFPROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat())
      LOCAL f%,x%,vs%
      vs%=0
      IF vf% AND 2 THEN vs%+=12:PRINT"vertices"
      IF vf% AND &10 THEN vs%+=12:PRINT "normals"
      IF vf% AND &40 THEN vs%+=4:PRINT "ambient colour"
      IF vf% AND &80 THEN vs%+=4:PRINT "specular colour"
      IF vf% AND &100 THEN vs%+=8:PRINT "Texture data"
      REM Create file and fill it with data
      f%=OPENOUT(@dir$+name$+".b3d")
      PRINT nv%
      PROC4(f%,nv%)
      PROC4(f%,(vs%<<16)+vf%)
      FOR x%=0 TO nv%-1
        IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
        IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
        IF vf% AND &40 THEN PROC4(f%,&FFFFFFFF)
        IF vf% AND &80 THEN PROC4(f%,&FFFFFFFF)
        IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
      NEXT x%
      CLOSE #f%
      ENDPROC
      :
      DEFPROCNormalise(nv%,n())
      LOCAL x%,l
      FOR x%=0 TO nv%-1 STEP 3
        l=SQR(n(x%,0)^2 + n(x%,1)^2+n(x%,2)^2)
        n(x%,0)/=l
        n(x%,1)/=l
        n(x%,2)/=l
      NEXT x%
      ENDPROC
      :
      REM Stolen from Richard's D3D demo
      DEF PROC4(F%, A%)
      BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
      ENDPROC
      :
      REM Convert to 4-byte float
      REM Stolen from Richard's D3D library
      DEF FN_f4(A#)
      LOCAL A%,P%,U#
      PRIVATE F%
      IF F%=0 THEN
        DIM P% 10
        [OPT 2
        .F%
        mov esi,[ebp+2]:mov edi,[ebp+7]
        fld qword [esi]:fstp dword [edi]
        ret
        ]
      ENDIF
      !(^U#+4)=&3FF00000
      A#*=U#
      CALL F%,A#,A%
      =A%
 
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #4 on: Sep 14th, 2017, 1:43pm »

Here's a small viewer, so you can look at the shapes generated. You'll need to amend "house.bmp" to a picture of your choice!

Best wishes,

D
Code:
      REM. Program to demonstrate use of Direct3D in BBC BASIC for Windows

      MODE 21
      DIM l%(1), b%(0), n%(0), f%(0), s%(0), m%(0), t%(0), y(0), p(0), r(0), X(0), Y(0), Z(0), e(2), a(2)


      INSTALL @lib$+"D3DLIB"
      PRINT "Loaded D3DLIB"
      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END

      DIM D3Dlight8{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% }
      D3Dlight8.Type% = 3 : REM directional source
      D3Dlight8.Diffuse.r% = FN_f4(1)
      D3Dlight8.Diffuse.g% = FN_f4(1)
      D3Dlight8.Diffuse.b% = FN_f4(1)
      D3Dlight8.Specular.r% = FN_f4(1)
      D3Dlight8.Specular.g% = FN_f4(1)
      D3Dlight8.Specular.b% = FN_f4(1)
      D3Dlight8.Direction.x% = FN_f4(1)
      D3Dlight8.Direction.y% = FN_f4(0.5)
      D3Dlight8.Direction.z% = FN_f4(0)
      l%(0) = D3Dlight8{}

      DIM D3Dlight2{}=D3Dlight8{}
      D3Dlight2.Type% = 3 : REM directional source
      D3Dlight2.Diffuse.r% = FN_f4(1)
      D3Dlight2.Diffuse.g% = FN_f4(1)
      D3Dlight2.Diffuse.b% = FN_f4(1)
      D3Dlight2.Specular.r% = FN_f4(1)
      D3Dlight2.Specular.g% = FN_f4(1)
      D3Dlight2.Specular.b% = FN_f4(1)
      D3Dlight2.Direction.x% = FN_f4(0)
      D3Dlight2.Direction.y% = FN_f4(-0.5)
      D3Dlight2.Direction.z% = FN_f4(1)
      l%(1) = D3Dlight2{}


      d% = FN_initd3d(@hwnd%, 1, 1)
      IF d% = 0 ERROR 100, "Can't initialise Direct3D"

      b%(0) = FN_load3d(d%, @dir$+"cylinder.b3d", n%(0), f%(0), s%(0))
      IF b%(0) = 0 ERROR 100, "Can't load B3D"


      t%(0) = FN_loadtexture(d%, @dir$+"house.bmp")
      IF t%(0) = 0 ERROR 100, "Can't load texture"

      e() = 0, 0, -5
      a() = 0, 0, 0
      REPEAT
        p() = TIME/200
        r() = TIME/100
        X() = SIN(TIME/200)
        PROC_render(d%, &FF50507F, 2, l%(), 1, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
      UNTIL INKEY(1)<>-1
      PROCcleanup
      END
      :
      DEF PROCcleanup
      t%(0) += 0:IF t%(0) PROC_release(t%(0))
      b%(0) += 0:IF b%(0) PROC_release(b%(0))
      d% += 0   :IF d%    PROC_release(d%)
      ENDPROC
 
User IP Logged

michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
xx Re: The 3D editor tool kit: ideas
« Reply #5 on: Sep 15th, 2017, 01:07am »

Impressive work. I think a secondary window (scratch pad editor) would be effective, even considering Richard wants a cross platform and BBC4W platform, a person would only need to run more than one instance of BBC Basic or create a executable for the interface and then make the renderer in a separate program and edit the image data in the file that the renderer would cycle and update.

The programs would simply be side by side in Windows 10 and could be quite simple.

I would like Hellomike , Ric, David Williams and all the others to visit the forum and perhaps we can each provide a perspective on advancing this. This can be fun for everyone.

I really want to make it so that it has super simple controls and also make it so a person can make 3D pieces from a preset pile of triangles. (12 to start in the beginners sandbox.)

If a person looks at how primitives are made in Second Life (game), that could give some ideas for making it simple,

Perhaps, triangles could be rendered in the 3D world to coordinate some edits.

Here is a link to Second Life 3D creation

https://youtu.be/5NvhL2YoIUY

And Hexagon 3D editor

https://youtu.be/4YsdMIHm_Po
« Last Edit: Sep 15th, 2017, 01:18am by michael » User IP Logged

I like making program generators and like reinventing the wheel
DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #6 on: Sep 15th, 2017, 11:53am »

Here's where I am on the library: it's too big for one post, so you'll need to copy this plus the next bit, and save it together as one file. You can either put it in your library folder (may need admin permission), and load with INSTALL @lib$+"Make3DLib", or save it in your working directory and install it from there.

Best wishes,

D
Code:
REM Make3dLib: A set of routines to create, manipulate and combine a range of primitive shapes,
 REM which can then be written to a file to be loaded by D3DLib or equivalents

 DEFFNGetNumVerts(n$,nf%,startface%,endface%,capped%)
 LOCAL nv%
 PROCUpcase(n$)
 CASE n$ OF
 WHEN "CYLINDER","PRISM","TRUNCCONE":
 IF capped% THEN vpf%=12 ELSE vpf%=6
 nv%=vpf%*(endface%-startface%+1)
 WHEN "SPHERE":
 nv%=(endface%-startface%+1)*2*nf% *6
 IF startface%=1 THEN nv%-=nf%*6
 IF endface%=nf% THEN nv%-=nf%*6
 WHEN "CONE":
 IF capped% THEN vpf%=6 ELSE vpf%=3
 nv%=vpf%*(endface%-startface%+1)
 ENDCASE
 =nv%
 :
 DEFPROCMake3D_Sphere(nf%,v(),n(),t(),startface%,endface%,texminu,texmaxu,textminv,texmaxv)
 LOCAL nv%,vn%
 nv%=(endface%-startface%+1)*2*nf% *6
 IF startface%=1 THEN nv%-=nf%*6
 IF endface%=nf% THEN nv%-=nf%*6
 r=1.0
 vn%=0
 IF startface%=1 THEN
 a=PI/nf%
 lr=r*SIN(a)
 FOR x%=0 TO 2*nf%-1
 a2=x%*PI/nf%
 px=-r*COS(a)
 py=lr*SIN(x%*PI/nf%)
 pz=lr*COS(x%*PI/nf%)
 py2=lr*SIN((x%+1)*PI/nf%)
 pz2=lr*COS((x%+1)*PI/nf%)
 v(vn%,0)=px
 v(vn%,1)=py
 v(vn%,2)=pz
 vn%+=1
 v(vn%,0)=-r
 v(vn%,1)=0
 v(vn%,2)=0
 vn%+=1
 v(vn%,0)=px
 v(vn%,1)=py2
 v(vn%,2)=pz2
 vn%+=1
 NEXT x%
 startface%+=1
 ENDIF
 IF endface%=nf% THEN
 a=PI/nf%
 lr=r*SIN(a)
 FOR x%=0 TO 2*nf%-1
 a2=x%*PI/nf%
 px=r*COS(a)
 py=lr*SIN(x%*PI/nf%)
 pz=lr*COS(x%*PI/nf%)
 py2=lr*SIN((x%+1)*PI/nf%)
 pz2=lr*COS((x%+1)*PI/nf%)
 v(vn%,0)=px
 v(vn%,1)=py
 v(vn%,2)=pz
 vn%+=1
 v(vn%,0)=r
 v(vn%,1)=0
 v(vn%,2)=0
 vn%+=1
 v(vn%,0)=px
 v(vn%,1)=py2
 v(vn%,2)=pz2
 vn%+=1
 NEXT x%
 endface%-=1
 ENDIF
 FOR y%=startface%-1 TO endface%-1
 a=y%*PI/nf%
 lr=r*SIN(a)
 px=-r*COS(a)
 a2=(y%+1)*PI/nf%
 lr2=r*SIN(a2)
 px2=-r*COS(a2)
 FOR x%=0 TO 2*nf%-1
 a=x%*PI/nf%
 py=lr*SIN(x%*PI/nf%)
 pz=lr*COS(x%*PI/nf%)
 py2=lr*SIN((x%+1)*PI/nf%)
 pz2=lr*COS((x%+1)*PI/nf%)
 a2=(x%+1)*PI/nf%
 ey=lr2*SIN(x%*PI/nf%)
 ez=lr2*COS(x%*PI/nf%)
 ey2=lr2*SIN((x%+1)*PI/nf%)
 ez2=lr2*COS((x%+1)*PI/nf%)
 v(vn%,0)=px
 v(vn%,1)=py
 v(vn%,2)=pz
 vn%+=1
 v(vn%,0)=px2
 v(vn%,1)=ey2
 v(vn%,2)=ez2
 vn%+=1
 v(vn%,0)=px2
 v(vn%,1)=ey
 v(vn%,2)=ez
 vn%+=1
 v(vn%,0)=px
 v(vn%,1)=py
 v(vn%,2)=pz
 vn%+=1
 v(vn%,0)=px
 v(vn%,1)=py2
 v(vn%,2)=pz2
 vn%+=1
 v(vn%,0)=px2
 v(vn%,1)=ey2
 v(vn%,2)=ez2
 vn%+=1
 NEXT x%
 NEXT y%
 FOR x%=0 TO vn%-1
 n(x%,0)=v(x%,0)*2
 n(x%,1)=v(x%,1)*2
 n(x%,2)=v(x%,2)*2
 t(x%,0)=r+v(x%,0)/2
 t(x%,1)=r+v(x%,1)/3
 NEXT x%
 IF vn%<>nv% THEN PRINT vn%,nv%:STOP
 ENDPROC
 :
 DEFPROCMake3D_Cone(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv)
 LOCAL a,pa,vpf%,nv%,l,r,tdu,tdv
 IF capped% THEN vpf%=6 ELSE vpf%=3
 nv%=vpf%*(endface%-startface%+1)
 l=1
 r=1.0
 tdu=texmaxu-texminu
 tdv=texmaxv-texminv
 FOR a=0 TO endface%-startface%
 pa=a+startface%-1
 py=r*SIN(pa*2*PI/nf%)
 pz=r*COS(pa*2*PI/nf%)
 py2=r*SIN((pa+1)*2*PI/nf%)
 pz2=r*COS((pa+1)*2*PI/nf%)
 v(a*vpf%,0)=0
 v(a*vpf%,1)=py
 v(a*vpf%,2)=pz
 v(a*vpf%+1,0)=0
 v(a*vpf%+1,1)=py2
 v(a*vpf%+1,2)=pz2
 v(a*vpf%+2,0)=l
 v(a*vpf%+2,1)=0
 v(a*vpf%+2,2)=0
 ny=(r+1)*SIN(pa*2*PI/nf%)
 nz=(r+1)*COS(pa*2*PI/nf%)
 ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
 nz2=(r+1)*COS((pa+1)*2*PI/nf%)
 vn(a*vpf%,0)=0
 vn(a*vpf%,1)=ny
 vn(a*vpf%,2)=nz
 vn(a*vpf%+1,0)=0
 vn(a*vpf%+1,1)=ny2
 vn(a*vpf%+1,2)=nz2
 vn(a*vpf%+2,0)=l
 vn(a*vpf%+2,1)=ny
 vn(a*vpf%+2,2)=nz
 t(a*vpf%,0)=texminu
 t(a*vpf%,1)=texminv+tdv*pa/nf%
 t(a*vpf%+1,0)=texminu
 t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
 t(a*vpf%+2,0)=texmaxu
 t(a*vpf%+2,1)=texminv+tdv*(pa+1)/nf%
 IF capped% THEN
 v(a*vpf%+3,0)=0
 v(a*vpf%+3,1)=py
 v(a*vpf%+3,2)=pz
 v(a*vpf%+4,0)=0
 v(a*vpf%+4,1)=0
 v(a*vpf%+4,2)=0
 v(a*vpf%+5,0)=0
 v(a*vpf%+5,1)=py2
 v(a*vpf%+5,2)=pz2
 vn(a*vpf%+3,0)=-1
 vn(a*vpf%+3,1)=py
 vn(a*vpf%+3,2)=pz
 vn(a*vpf%+4,0)=-1
 vn(a*vpf%+4,1)=0
 vn(a*vpf%+4,2)=0
 vn(a*vpf%+5,0)=-1
 vn(a*vpf%+5,1)=py2
 vn(a*vpf%+5,2)=pz2
 vn(a*vpf%+9,0)=l+1
 vn(a*vpf%+9,1)=py
 vn(a*vpf%+9,2)=pz
 vn(a*vpf%+10,0)=l+1
 vn(a*vpf%+10,1)=0
 vn(a*vpf%+10,2)=0
 vn(a*vpf%+11,0)=l+1
 vn(a*vpf%+11,1)=py2
 vn(a*vpf%+11,2)=pz2
 t(a*vpf%+3,0)=texminu+tdu*a/nf%
 t(a*vpf%+3,1)=texminv
 t(a*vpf%+4,0)=texminu+tdu/2
 t(a*vpf%+4,1)=texmaxv
 t(a*vpf%+5,0)=texminu+tdu*(a+1)/nf%
 t(a*vpf%+5,1)=texminv
 ENDIF
 NEXT a
 PRINT nv%
 ENDPROC
 :
 DEFPROCMake3D_Prism(nf%,v(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=FALSE
 DEFPROCMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=TRUE
 LOCAL r,r2
 r=1
 r2=1
 DEFPROCMake3D_TruncCone(r,r2,nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,textminv,texmaxv):Make3dLibNormals%=TRUE
 LOCAL a,pa,vpf%,nv%,l,tdu,tdv
 IF capped% THEN vpf%=12 ELSE vpf%=6
 nv%=vpf%*(endface%-startface%+1)
 l=1
 tdu=texmaxu-texminu
 tdv=texmaxv-texminv
 FOR a=0 TO endface%-startface%
 pa=a+startface%-1
 py=r*SIN(pa*2*PI/nf%)
 pz=r*COS(pa*2*PI/nf%)
 py2=r*SIN((pa+1)*2*PI/nf%)
 pz2=r*COS((pa+1)*2*PI/nf%)
 ey=r2*SIN(pa*2*PI/nf%)
 ez=r2*COS(pa*2*PI/nf%)
 ey2=r2*SIN((pa+1)*2*PI/nf%)
 ez2=r2*COS((pa+1)*2*PI/nf%)
 v(a*vpf%,0)=0
 v(a*vpf%,1)=py
 v(a*vpf%,2)=pz
 v(a*vpf%+1,0)=l
 v(a*vpf%+1,1)=ey2
 v(a*vpf%+1,2)=ez2
 v(a*vpf%+2,0)=l
 v(a*vpf%+2,1)=ey
 v(a*vpf%+2,2)=ez
 v(a*vpf%+3,0)=0
 v(a*vpf%+3,1)=py
 v(a*vpf%+3,2)=pz
 v(a*vpf%+4,0)=0
 v(a*vpf%+4,1)=py2
 v(a*vpf%+4,2)=pz2
 v(a*vpf%+5,0)=l
 v(a*vpf%+5,1)=ey2
 v(a*vpf%+5,2)=ez2
 IF Make3dLibNormals% THEN
 ny=(r+1)*SIN(pa*2*PI/nf%)
 nz=(r+1)*COS(pa*2*PI/nf%)
 ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
 nz2=(r+1)*COS((pa+1)*2*PI/nf%)
 eny=(r2+1)*SIN(pa*2*PI/nf%)
 enz=(r2+1)*COS(pa*2*PI/nf%)
 eny2=(r2+1)*SIN((pa+1)*2*PI/nf%)
 enz2=(r2+1)*COS((pa+1)*2*PI/nf%)
 vn(a*vpf%,0)=0
 vn(a*vpf%,1)=ny
 vn(a*vpf%,2)=nz
 vn(a*vpf%+1,0)=l
 vn(a*vpf%+1,1)=eny2
 vn(a*vpf%+1,2)=enz2
 vn(a*vpf%+2,0)=l
 vn(a*vpf%+2,1)=eny
 vn(a*vpf%+2,2)=enz
 vn(a*vpf%+3,0)=0
 vn(a*vpf%+3,1)=ny
 vn(a*vpf%+3,2)=nz
 vn(a*vpf%+4,0)=0
 vn(a*vpf%+4,1)=ny2
 vn(a*vpf%+4,2)=nz2
 vn(a*vpf%+5,0)=l
 vn(a*vpf%+5,1)=eny2
 vn(a*vpf%+5,2)=enz2
 ENDIF
 t(a*vpf%,0)=texminu
 t(a*vpf%,1)=texminv+tdv*pa/nf%
 
 t(a*vpf%+1,0)=texmaxu
 t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
 
 t(a*vpf%+2,0)=texmaxu
 t(a*vpf%+2,1)=texminv+tdv*pa/nf%
 
 t(a*vpf%+3,0)=texminu
 t(a*vpf%+3,1)=texminv+tdv*pa/nf%
 
 t(a*vpf%+4,0)=texminu
 t(a*vpf%+4,1)=texminv+tdv*(pa+1)/nf%
 
 t(a*vpf%+5,0)=texmaxu
 t(a*vpf%+5,1)=texminv+tdv*(pa+1)/nf%
 IF capped% THEN
 v(a*vpf%+6,0)=0
 v(a*vpf%+6,1)=py
 v(a*vpf%+6,2)=pz
 v(a*vpf%+7,0)=0
 v(a*vpf%+7,1)=0
 v(a*vpf%+7,2)=0
 v(a*vpf%+8,0)=0
 v(a*vpf%+8,1)=py2
 v(a*vpf%+8,2)=pz2
 v(a*vpf%+9,0)=l
 v(a*vpf%+9,1)=ey
 v(a*vpf%+9,2)=ez
 v(a*vpf%+10,0)=l
 v(a*vpf%+10,1)=0
 v(a*vpf%+10,2)=0
 v(a*vpf%+11,0)=l
 v(a*vpf%+11,1)=ey2
 v(a*vpf%+11,2)=ez2
 IF Make3dLibNormals% THEN
 vn(a*vpf%+6,0)=-10
 vn(a*vpf%+6,1)=py
 vn(a*vpf%+6,2)=pz
 vn(a*vpf%+7,0)=-10
 vn(a*vpf%+7,1)=0
 vn(a*vpf%+7,2)=0
 vn(a*vpf%+8,0)=-10
 vn(a*vpf%+8,1)=py2
 vn(a*vpf%+8,2)=pz2
 vn(a*vpf%+9,0)=l+10
 vn(a*vpf%+9,1)=ey2
 vn(a*vpf%+9,2)=ez2
 vn(a*vpf%+10,0)=l+10
 vn(a*vpf%+10,1)=0
 vn(a*vpf%+10,2)=0
 vn(a*vpf%+11,0)=l+10
 vn(a*vpf%+11,1)=ey2
 vn(a*vpf%+11,2)=ez2
 ENDIF
 t(a*vpf%+6,0)=texminu+tdu*a/nf%
 t(a*vpf%+6,1)=texminv
 t(a*vpf%+7,0)=texminu+tdu/2
 t(a*vpf%+7,1)=texmaxv
 t(a*vpf%+8,0)=texminu+tdu*(a+1)/nf%
 t(a*vpf%+8,1)=texminv
 t(a*vpf%+9,0)=texminu+tdu*a/nf%
 t(a*vpf%+9,1)=texminv
 t(a*vpf%+10,0)=texminu+tdu/2
 t(a*vpf%+10,1)=texmaxv
 t(a*vpf%+11,0)=texminu+tdu*(a+1)/nf%
 t(a*vpf%+11,1)=texminv
 ENDIF
 NEXT a
 ENDPROC
 :
 DEFPROCRotate(a(),xa,ya,za)
 LOCAL xrm(),yrm(),zrm()
 DIM xrm(2,2),yrm(2,2),zrm(2,2)
 xrm()=1,0,0,0,COS(xa),-SIN(xa),0,SIN(xa),COS(xa)
 yrm()=COS(ya),0,SIN(ya),0,1,0,-SIN(ya),0,COS(ya)
 zrm()=COS(za),-SIN(za),0,SIN(za),COS(za),0,0,0,1
 xrm()=xrm().yrm()
 xrm()=xrm().zrm()
 a()=a().xrm()
 ENDPROC
 :
 DEFPROCShift(a(),dx,dy,dz,nv%)
 LOCAL x%
 FOR x%=0 TO nv%-1
 a(x%,0)+=dx
 a(x%,1)+=dy
 a(x%,2)+=dz
 NEXT x%
 ENDPROC
 :
 DEFPROCShear(nv%,a(),xs,ys,zs)
 LOCAL x%,maxx,maxy,maxz
 FOR x%=0 TO nv%-1
 IF ABS(a(x%,0))>maxx THEN maxx=ABS(a(x%,0))
 IF ABS(a(x%,1))>maxy THEN maxy=ABS(a(x%,1))
 IF ABS(a(x%,2))>maxz THEN maxz=ABS(a(x%,2))
 NEXT x%
 FOR x%=0 TO nv%-1
 a(x%,1)+=xs*a(x%,0)/maxx
 a(x%,2)+=ys*a(x%,1)/maxy
 a(x%,0)+=zs*a(x%,2)/maxz
 NEXT x%
 ENDPROC
 :
 DEFPROCDisplay(v(),n(),nv%)
 LOCAL x%,xoff,yoff,zoff,xr,yr,zr
 xoff=1000
 yoff=700
 zoff=0
 xr=0
 yr=0
 zr=0
 *REFRESH OFF
 FOR zr=0 TO 2*PI STEP 0.1
 yr=zr/2
 xr=zr/3
 vr()=v()
 vr()*=100
 vnr()=vn()
 vnr()*=100
 PROCRotate(vr(),xr,yr,zr)
 PROCShift(vr(),xoff,yoff,0,nv%)
 PROCRotate(vnr(),xr,yr,zr)
 PROCShift(vnr(),xoff,yoff,0,nv%)
 FOR x%=0 TO nv%-2 STEP 3
 MOVE vr(x%,0),vr(x%,1)
 DRAW vr(x%+1,0),vr(x%+1,1)
 DRAW vr(x%+2,0),vr(x%+2,1)
 LINE vr(x%,0),vr(x%,1),vnr(x%,0),vnr(x%,1)
 NEXT x%
 *REFRESH
 WAIT 5
 CLS
 NEXT zr
 *REFRESH ON
 ENDPROC
 :
 DEFPROCNormalise(nv%,n())
 LOCAL x%,l
 FOR x%=0 TO nv%-1 STEP 3
 l=SQR(n(x%,0)^2 + n(x%,1)^2+n(x%,2)^2)
 IF l<>0 THEN
 n(x%,0)/=l
 n(x%,1)/=l
 n(x%,2)/=l
 ENDIF
 NEXT x%
 ENDPROC
 :
 DEFPROCStretch(nv%,v(),xf,yf,zf)
 LOCAL x%
 FOR x%=0 TO nv%-1
 v(x%,0)*=xf
 v(x%,1)*=yf
 v(x%,2)*=zf
 NEXT x%
 ENDPROC
 :
 DEFPROCFindNormals(nv%,v(),n())
 LOCAL a,b,c,d,e,f,x%,y%,t()
 DIM t(2)
 REM Modified slightly from Richard's "lighting" program
 FOR x%=0 TO nv%-2 STEP 3
 a = v(x%+1,0) - v(x%+2,0)
 b = v(x%+1,1) - v(x%+2,1)
 c = v(x%+1,2) - v(x%+2,2)
 d = v(x%,0) - v(x%+2,0)
 e = v(x%,1) - v(x%+2,1)
 f = v(x%,2) - v(x%+2,2)
 t(0) = b*f-c*e
 t(1) = c*d-a*f
 t(2) = a*e-b*d
 t() /= MOD(t())
 FOR y%=0 TO 2
 n(x%+y%,0) = t(0)
 n(x%+y%,1) = t(1)
 n(x%+y%,2) = t(2)
 NEXT y%
 NEXT x%
 ENDPROC
 
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #7 on: Sep 15th, 2017, 12:07pm »

The first part had the routines for making and manipulating the primitives: this part is the routines for writing them to a B3D file (that's what Richard calls them, so I've stuck with that nomenclature).

You can either use "PROCWriteB3D", which writes a single set of data to a file, or you can use the more complex but more flexible routine of:

FNOpenB3D (to open the file and write the initial data. Note that you need to know the total number of vertices you will need before you do that! returns a file handle needed to extend and close it)

Then use

PROCExtendB3D to write each component in turn.

Once you've sent them all to the file,

PROCCloseB3D

Note that using this approach means that each component can be a different colour. If you want different vertices to be different colours you'll need to make some changes! More sensibly, you can map a texture to the shape (but you can only have one texture for the whole, combined, shape.)

You can specify which part of the texture is used to cover each component,so you could have a "patchwork" texture, and use the relevant bit. I'll work on an example at some point.

There are a few other routines to put numbers into SINGLE format, stolen from Richard's 3D code, and one to change a text string to upper case, for convenience in the routine where you can ask what size a buffer needs to be.

I'll post some code using this library to make the starship Enterprise, as an example.

Then I'll post some instructions on how to use the routines.

Best wishes,

D
Code:
 :
 DEFPROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat(),acol%,scol%)
 LOCAL f%,x%,vs%
 vs%=0
 IF vf% AND 2 THEN vs%+=12
 IF vf% AND &10 THEN vs%+=12
 IF vf% AND &40 THEN vs%+=4
 IF vf% AND &80 THEN vs%+=4
 IF vf% AND &100 THEN vs%+=8
 REM Create file and fill it with data
 f%=OPENOUT(@dir$+name$+".b3d")
 PRINT nv%
 PROC4(f%,nv%)
 PROC4(f%,(vs%<<16)+vf%)
 FOR x%=0 TO nv%-1
 IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
 IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
 IF vf% AND &40 THEN PROC4(f%,acol%)
 IF vf% AND &80 THEN PROC4(f%,scol%)
 IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
 NEXT x%
 CLOSE #f%
 ENDPROC
 :
 DEFFNOpenB3D(name$,nv%,vf%)
 LOCAL f%,x%,vs%
 vs%=0
 IF vf% AND 2 THEN vs%+=12
 IF vf% AND &10 THEN vs%+=12
 IF vf% AND &40 THEN vs%+=4
 IF vf% AND &80 THEN vs%+=4
 IF vf% AND &100 THEN vs%+=8
 REM Create file and fill it with data
 f%=OPENOUT(@dir$+name$+".b3d")
 PROC4(f%,nv%)
 PROC4(f%,(vs%<<16)+vf%)
 =f%
 :
 DEFPROCCloseB3D(f%)
 CLOSE #f%
 ENDPROC
 :
 DEFPROCExtendB3D(f%,vf%,nv%,vdat(),ndat(),tdat(),acol%,scol%)
 LOCAL x%
 FOR x%=0 TO nv%-1
 IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
 IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
 IF vf% AND &40 THEN PROC4(f%,acol%)
 IF vf% AND &80 THEN PROC4(f%,scol%)
 IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
 NEXT x%
 ENDPROC
 :
 DEFPROCUpcase(RETURN n$)
 LOCAL x%
 FOR x%=1 TO LEN(n$)
 IF ASC(MID$(n$,x%,1))>96 AND ASC(MID$(n$,x%,1))<123 THEN n$=LEFT$(n$,x%-1)+CHR$(ASC(MID$(n$,x%,1))-32)+MID$(n$,x%+1)
 NEXT x%
 ENDPROC
 :
 REM Stolen from Richard's D3D demo
 DEF PROC4(F%, A%)
 BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
 ENDPROC
 :
 REM Stolen from Richard's D3D library
 DEF FN_f4(A#)
 LOCAL A%,P%,U#
 PRIVATE F%
 IF F%=0 THEN
 DIM P% 10
 [OPT 2
 .F%
 mov esi,[ebp+2]:mov edi,[ebp+7]
 fld qword [esi]:fstp dword [edi]
 ret
 ]
 ENDIF
 !(^U#+4)=&3FF00000
 A#*=U#
 CALL F%,A#,A%
 =A%
 
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #8 on: Sep 15th, 2017, 12:26pm »

Here is the code to generate a B3D file holding a model something like the starship Enterprise.

Code:
      REM A Demonstration program using Make3DLib to generate a model of the Starship Enterprise

      INSTALL "Make3dLib.BBC"

      capped%=TRUE   :REM Include ends on the cylinder
      nf%=20       :REM Number of faces
      startface%=1   :REM Include the whole cylinder, or only part of it?
      endface%=10
      REM Coordinates to map a texture to the shape. You might want to use only a small part of a texture
      texminu=0
      texmaxu=1
      texminv=0
      texmaxv=1

      maxnv%=FNGetNumVerts("sphere",nf%,1,nf%,TRUE)
      DIM v(maxnv%,2),vn(maxnv%,2),t(maxnv%,1)  :REM hold vertex, normal, and texture data
      DIM vr(maxnv%,2),vnr(maxnv%,2)         :REM These are only needed for the display routine
      nf%=10

      REM We need to count up all the vertices that will be used in all the sections, so that we can put it at the beginning of the file
      tnv%=4*FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)+1*FNGetNumVerts("sphere",nf%,1,nf%,FALSE)+4*FNGetNumVerts("sphere",nf%,6,nf%,FALSE)+4*FNGetNumVerts("prism",5,1,5,FALSE)
      vform%=&52       :REM Here I'm making a file with vertex, normal, and colour data
      fh%=FNOpenB3D("Enterprise",tnv%,vform%)

      nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
      PROCMake3D_TruncCone(1.0,0.5,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),-0.5,1,1)
      REM Normals for smooth shapes are initially generated as their endpoints, so that can be scaled etc,
      REM So we need to carry out any transformations on them in parallel
      PROCStretch(nv%,vn(),-0.5,1,1)
      REM Now we need to convert the normals to normalised vectors
      vn()=vn()-v()
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
      PROCMake3D_TruncCone(1.0,0.5,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),4,1,1)
      PROCStretch(nv%,vn(),4,1,1)
      vn()=vn()-v()                  :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
      PROCMake3D_TruncCone(0.5,0.4,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),4,1,1)
      PROCStretch(nv%,vn(),4,1,1)
      PROCShift(v(),2,2.5,2.5,nv%)
      PROCShift(vn(),2,2.5,2.5,nv%)
      vn()=vn()-v()                  :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("trunccone",nf%,1,nf%,TRUE)
      PROCMake3D_TruncCone(0.5,0.4,nf%,v(),vn(),t(),1,nf%,TRUE,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),4,1,1)
      PROCStretch(nv%,vn(),4,1,1)
      PROCShift(v(),2,2.5,-2.5,nv%)
      PROCShift(vn(),2,2.5,-2.5,nv%)
      vn()=vn()-v()                  :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,1,nf%,TRUE)
      PROCMake3D_Sphere(nf%,v(),vn(),t(),1,nf%,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),3,0.2,3)
      PROCStretch(nv%,vn(),3,0.2,3)
      PROCShift(v(),-2,1.5,0,nv%)
      PROCShift(vn(),-2,1.5,0,nv%)
      vn()=vn()-v()                  :REM "Normals" are initially generated as their endpoints, so that can be scaled etc, but now need to be converted to vectors
      PROCNormalise(nv%,vn())
      PROCFindNormals(nv%,v(),vn())  :REM Cheat: something is going wrong with normals of sphere by flattening it so much: cheat by using triangles directly - OK when this flat
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nf%=4
      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
      PROCRotate(v(),PI/4,0,0)
      PROCStretch(nv%,v(),3.5,0.5,0.2)
      PROCRotate(v(),0,0,-PI/2)
      PROCRotate(v(),-PI/4,0,0)
      PROCShift(v(),2.5,0,0,nv%)
      PROCFindNormals(nv%,v(),vn())  :REM With facetted shapes we can simply calculate the normals after all the messing around
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
      PROCRotate(v(),PI/4,0,0)
      PROCStretch(nv%,v(),3.5,0.5,0.2)
      PROCRotate(v(),0,0,-PI/2)
      PROCRotate(v(),PI/4,0,0)
      PROCShift(v(),2.5,0,0,nv%)
      PROCFindNormals(nv%,v(),vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
      PROCRotate(v(),PI/4,0,0)
      PROCStretch(nv%,v(),1.5,0.5,0.3)
      PROCShear(nv%,v(),2,0,0)
      PROCRotate(v(),0,0,-PI/2)
      PROCShift(v(),1,0,0,nv%)
      PROCFindNormals(nv%,v(),vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,texminu,texmaxu,textminv,texmaxv)
      PROCRotate(v(),PI/4,0,0)
      PROCStretch(nv%,v(),0.5,0.1,0.1)
      PROCShift(v(),-1,0,0,nv%)
      PROCFindNormals(nv%,v(),vn())  :REM Cheating here - the flattening is messing with the normals, so I've just treated it as a facetted surface
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF804040,&FFFFFFFF)

      nf%=10
      nv%=FNGetNumVerts("sphere",nf%,6,nf%,TRUE)
      PROCMake3D_Sphere(nf%,v(),vn(),t(),6,nf%,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),0.2,0.5,0.5)
      PROCStretch(nv%,vn(),0.2,0.5,0.5)
      PROCShift(v(),-0.8,0,0,nv%)
      PROCShift(vn(),-0.8,0,0,nv%)
      vn()=vn()-v()
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF804040,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,1,5,TRUE)
      PROCMake3D_Sphere(nf%,v(),vn(),t(),1,5,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),0.4,0.4,0.4)
      PROCStretch(nv%,vn(),0.4,0.4,0.4)
      PROCShift(v(),2,2.5,-2.5,nv%)
      PROCShift(vn(),2,2.5,-2.5,nv%)
      vn()=vn()-v()
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FFF04040,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,1,5,TRUE)
      PROCMake3D_Sphere(nf%,v(),vn(),t(),1,5,texminu,texmaxu,textminv,texmaxv)
      PROCStretch(nv%,v(),0.4,0.4,0.4)
      PROCStretch(nv%,vn(),0.4,0.4,0.4)
      PROCShift(v(),2,2.5,2.5,nv%)
      PROCShift(vn(),2,2.5,2.5,nv%)

      vn()=vn()-v()
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FFF04040,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,6,nf%,TRUE)
      PROCMake3D_Sphere(nf%,v(),vn(),t(),6,nf%,texminu,texmaxu,textminv,texmaxv)
      PROCRotate(v(),0,0,-PI/2)
      PROCRotate(vn(),0,0,-PI/2)
      PROCStretch(nv%,v(),1,0.3,0.5)
      PROCStretch(nv%,vn(),1,0.3,0.5)
      PROCShift(v(),-1.7,1.7,0,nv%)
      PROCShift(vn(),-1.7,1.7,0,nv%)
      vn()=vn()-v()
      PROCNormalise(nv%,vn())
      PROCExtendB3D(fh%,vform%,nv%,v(),vn(),t(),&FF808080,&FFFFFFFF)

      PROCCloseB3D(fh%)

      PRINT "Success!"
      END
 
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #9 on: Sep 15th, 2017, 9:59pm »

Here are my comments, in the form of REMs which can be pasted at the head of the library
Code:
      REM Make3dLib: A set of routines to create, manipulate and combine a range of primitive shapes,
      REM which can then be written to a file to be loaded by D3DLib or equivalents

      REM For each shape you can specify the number of faces (nf%) making up up the "cylinder" it fits in,
      REM controlling how good the mapping to a circular profile is.
      REM You can also specify which of these sides to start and end drawing at, allowing you to produce part-shapes-
      REM so the sphere routine can make hemispheres, or "collars", or the cylinder routine can make bulges on the side of something.
      REM Rather perversely, startface%=1 means the first one, and endface%=nf% means the last one - unlike almost everything else it isn't 0-based.
      REM You can specify that capped% is TRUE or FALSE: if true, the ends of cylinders etc will be filled.

      REM By default, the resulting mesh will have a length 1 and/or radius 1, but by changing the r or l parameters in the routine you can change this.
      REM It's probably better to leave it as 1, and then scale the figures later.

      REM Cylinders, cones etc all have the origin in the middle of their base, and extend positively along the X axis (to 1).
      REM Spheres are centred on the origin (so extend from -1 to 1).
      REM For truncated Cylinders you can specify a starting and ending radius: the starting one will apply at x=0 and the ending one at x=1. Either can be larger.

      REM At present, all routines generate vertices, and texture mapping coordinates.
      REM All "smooth"-surfaced ones (cylinder, cone, truncated cone, sphere) also generate normals-  but do so by generating the endpoint of the normal.
      REM This is so that shapes can be manipulated, with the array of normal-ends being manipulated in parallel, to maintain them. This is a bit clumsy, but useful.
      REM For facetted shapes (prisms) it's easier to generate the normals at the end, using PROCFindNormals, from the coordinates of each triangle (since all 3 points share the same normal).
      REM You can do the same for any of the smooth shapes, to create facetted equivalents - simply send the array of normals to PROCFindNormal, and they will be overwritten.

      REM In general, you need to create a set of arrays, to hold vertices (xyz values), normals (xyz values), and texture coordinates (uv values, equivalent to xy coordinates on the texture, scaled between 0 and 1).
      REM Each of these needs to have a first dimension of (at least) the number of vertices to be generated. FNGetNumVerts() will return this.
      REM All arrays are 0-based. So, for example, having determined that you need nv% vertices, you might DIM v(nv%-1,2), n(nv%-1,2),t(nv%-1,1)
      REM v(x%,0) refers to the x coordinate, v(x%,1) refers to the y coordinate, and v(x%,2) refers to the z coordinate of point x% (the first point is at x%=0).
      REM It's probably best to work out the most complex shape you will need, then DIM the arrays for that - then you can recycle them.
      REM Spheres are by far the biggest, so if you choose arrays to hold, say, a 20-sided sphere, which needs 4560 vertices, you should be OK.
      REM Go much bigger and you are likely to need to raise HIMEM....

      REM FNGetNumVerts(n$,nf%,startface%,endface%,capped%) takes the name of a shape (cylinder,prism, trunccone,sphere,cone; case insensitive) and other elements as noted above, and returns the number of vertices generated

      REM PROCMake3D_Sphere(nf%,v(),n(),t(),startface%,endface%,texminu,texmaxu,texminv,texmaxv) Generates a sphere, or part of one, returning vertices in v(),normals in n() and texture coordinates in t()
      REM PROCMake3D_Cone(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) similarly generates a cone
      REM PROCMake3D_Prism(nf%,v(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) Generates a prism (flat-sided structure, where edges are parallel to x axis).
      REM                                            An equivalent effect can be generated by using PROCMake3D_Cylinder() and then using PROCFindNormals.
      REM PROCMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) Generates a cylinder
      REM PROCMake3D_TruncCone(r,r2,nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv) generates a truncated cone, tapering from r to r1 as it goes from 0 to 1 on the x axis

      REM All these routines take minimum and maximum values for U andd V coordinates for texture mapping set these to 0 and 1 respectively to use the whole texture, or subfractions of this to use a bit of a "patchwork" texture

      REM Then there are a series of routines to modify the basic primitives:

      REM PROCRotate(a(),xa,ya,za) takes an array of coordinates, and rotates them around the x axis by xa radians, around the y axis by ya radians, and around the z axis by za radians
      REM It does it in this order, and that is important! You can do all three at once, but it may be easier to visualise if you do one at a time!

      REM PROCShift(a(),dx,dy,dz,nv%) takes an array of coordinates, and shifts the whole thing as specified in the x,y, and z directions

      REM PROCStretch(nv%,v(),xf,yf,zf) takes an array of coordinates and stretches it in each direction by the factor specified. You could make them all the same to scale it, but...
      REM You can scale a whole array by simply multiplying it by the relevant scale factor (for example, v()*=3 )

      REM PROCShear(nv%,a(),xs,ys,zs) Shears the shape along the x axis in the y direction by xs, along the y axis in the z direction by ys, and along the z axis in the x direction by zs
      REM This seemed a good idea at the time, but is hard to use. I'll probably change it in future versions to specify the amount of shear, the axis along which it's applied, and the direction to change
      REM That will break existing uses, but be much more user friendly.

      REM PROCNormalise(nv%,n()) takes an array of normals, and normalises them to a vector length of 1.
      REM If you've got a set of normal end points generated by one of the smoooth routines (sphere, cone, etc) you should convert them to vectors (by subtracting the underlying vertex address) and then normalise them
      REM For example you could do n()-=v():PROCNormalise(nv%,n())

      REM PROCFindNormals(nv%,v(),n()) takes an array of vertices and calculates the (normalised) normals to each triangle, then sticks them in the normals array for each point of the triangle
      REM If you have/want a shape with flat faces, you can just pass it the vertex array once all your fiddling around has been done, and just before you want to write it to a file.

      REM PROCDisplay(v(),n(),nv%) will display a wire-frame version of your shape, with the normal for the first point of each triangle sticking out.
      REM It's really for diagnostic use, but I've left it in. You might want to fiddle with the offset and scaling values depending on your display.

      REM PROCWriteB3D(name$,nv%,vf%,vdat(),ndat(),tdat(),acol%,scol%) writes a whole file at once, based on a single set of buffers. You need to supply the vertex format - have a look at the the manual for details

      REM FNOpenB3D(name$,nv%,vf%) Opens a file, and writes the vertex format and size (calculated itself from the format) as well as the total number of vertices to be written to it.
      REM returns a handle to the file

      REM  PROCCloseB3D(f%) Go on - have a wild guess! The parameter is the file handle returned by FNOpenB3D

      REM PROCExtendB3D(f%,vf%,nv%,vdat(),ndat(),tdat(),acol%,scol%) Writes data from one set of arrays to the file previously opened. acol% and scol% are colours for ambient and specular lighting, respectively.
      REM Only the data specified by the vertex format code is actually written

      REM PROCUpcase(RETURN n$) Takes a string, and returns it with all lower case letters converted to upper case. Non-alphabetic characters are left untouched

      REM PROC4(F%, A%) Routine stolen from Richard's D3D programs; it writes 4 bytes to the file

      REM FN_f4(A#) Routine stolen from Richard's D3D programs; it takes a float variable and converts it to a "single" (i.e. 32 bit float), returned in an integer variable. This is the format required by Direct3D

 
User IP Logged

michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
xx Re: The 3D editor tool kit: ideas
« Reply #10 on: Sep 16th, 2017, 02:14am »

Very nice work! Ill get some shapes made this weekend.
User IP Logged

I like making program generators and like reinventing the wheel
michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
question Re: The 3D editor tool kit: ideas
« Reply #11 on: Sep 24th, 2017, 01:16am »

DDRM, would you be so kind as to repost the 3D tools you provided on Richards Forum? I am sure he would be happy to see this on his forum.

I cant do it, as it would be improper. I think he would like this very much as a contribution.

Also I hope to surprise everyone on Monday night with a useable object editor for both forums on one screen for both BBC4W and BBCSDL.

I appreciate this DDRM !!
User IP Logged

I like making program generators and like reinventing the wheel
DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #12 on: Sep 24th, 2017, 6:35pm »

Hi Folks,

I've posted my current version of "Make3DLib" in the libraries section of the files section of the groups.io discussion group.

https://groups.io/g/bb4w/files/Libraries/Make3dLib.bbc

It does one naughty thing - it uses a global variable to facilitate "overloading" of the routines.

You may need to be logged in as a member to get it. It's slightly updated from the version I posted on the BB4W conforum - most significantly with much better texture mapping to some shapes.

It has fairly copious notes at the beginning about what routines are included, and how to use them, and I've got some sort examples which give an idea. It can make spheres, cones,cylinders, truncated cones (and, indirectly prisms) prisms and write them either singly or en masses to an FVF file. You can include coordinates, normals, texture coordinates, and ambient and specular colours, depending on the vertex format code you specify. There are also routines to modify the shapes (shear/stretch/rotate/translate), so you can align them to make more complex shapes.

I will add some more primitives (torus and "cove" are on my list - the latter once I work out how to calculate the external centre of curvature!

Best wishes,

D
User IP Logged

DDRM
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM

Gender: Male
Posts: 321
xx Re: The 3D editor tool kit: ideas
« Reply #13 on: Sep 27th, 2017, 2:03pm »

Here's an example which:
1) Generates a bitmap file to use as a texture
2) Makes a model of a jewel-hilted sword and saves it as an FVF file.

As a clarification on why this is now an FVF file not a B3D file, Richard has clarified that this is a better nomenclature: he chose B3D not realising it already had a use in the "graphics market". FVF stands for "flexible vertex format", which is what Microsoft call it.

I've assumed that you will save this file into the same directory as your "viewer", so the bitmap will be accessible. I've also assumed Make3DLib is in the same folder: if not, amend the INSTALL call appropriately (for example, by adding @libs$+).

You can use the viewer I listed below, but you'll need to change the file loaded into b%(0) to "sword.fvf",and the texture loaded into t%(0) to "swordtexture.bmp".

Note that the bitmap is made up of four regions, each of which is used in different parts of the sword. The texminu/texmaxu/texminv/texmaxv parameters are used to set the texture coordinates appropriately.

You'll need to use the most recent version of the library, posted on the groups.io site (see link below) to get correct rendering of the bitmap to the shape.
Here's the link again:
https://groups.io/g/bb4w/files/Libraries/Make3dLib.bbc

Best wishes,

D

Code:
      
INSTALL "Make3DLib"
      MODE 21
      GCOL 7
      RECTANGLE FILL 100,100,512,256
      FOR x%=1 TO 3
        FOR y%=1 TO 3
          PROCPoly(8,0,x%*60+100,100+60*y%,20,20,1,9)
        NEXT y%
      NEXT x%
      GCOL 0
      LINE 356,150,480,150
      LINE 356,180,480,180
      LINE 356,280,480,280
      LINE 356,310,480,310
      FOR x%=100 TO 356 STEP 16
        GCOL 0
        RECTANGLE FILL x%,356,4,256
        GCOL 8
        RECTANGLE FILL x%+4,356,12,256
        GCOL 7
        RECTANGLE FILL x%+8,356,2,256
      NEXT x%
      GCOL 3
      RECTANGLE FILL 356,356,256,256
      *GSAVE swordtexture.bmp 100,100,512,512

      nf%=6

      maxverts%=FNGetNumVerts("Sphere",nf%,1,nf%,TRUE)
      DIM v(maxverts%-1,2),n(maxverts%-1,2),t(maxverts%-1,1)
      nf%=6
      totalverts%=2*FNGetNumVerts("prism",nf%,1,nf%,FALSE)+FNGetNumVerts("cone",nf%,1,nf%,FALSE)+FNGetNumVerts("prism",4,1,4,FALSE)+3*FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
      vf%=&152
      f%=FNOpenFVF("sword",totalverts%,vf%)

      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.5,0.75,0,0.5)
      PROCStretch(nv%,v(),3,0.1,0.3)
      PROCFindNormals(nv%,v(),n())
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nv%=FNGetNumVerts("cone",nf%,1,nf%,FALSE)
      PROCMake3D_Cone(nf%,v(),n(),t(),1,nf%,FALSE,0.75,1.0,0,0.5)
      PROCStretch(nv%,v(),0.5,0.1,0.3)
      PROCShift(v(),3,0,0,nv%)
      PROCFindNormals(nv%,v(),n())
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.0,0.5,0.5,1.0)
      PROCStretch(nv%,v(),1,0.15,0.15)
      PROCShift(v(),-1,0,0,nv%)
      PROCFindNormals(nv%,v(),n())
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nf%=4
      nv%=FNGetNumVerts("prism",nf%,1,nf%,FALSE)
      PROCMake3D_Prism(nf%,v(),t(),1,nf%,FALSE,0.5,1.0,0.5,1.0)
      PROCShift(v(),-0.5,0,0,nv%)
      PROCStretch(nv%,v(),1.5,0.15,0.15)
      PROCRotate(v(),-PI/4,PI/2,0)
      PROCFindNormals(nv%,v(),n())
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nf%=6
      nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
      PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.1,0.4)
      v()*=0.2
      n()*=0.2
      PROCRotate(v(),PI,0,0)
      PROCRotate(n(),PI,0,0)
      PROCShift(v(),0,0,-0.75,nv%)
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
      PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.1,0.4)
      v()*=0.2
      n()*=0.2
      PROCShift(v(),0,0,0.75,nv%)
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      nv%=FNGetNumVerts("sphere",nf%,1,nf%,FALSE)
      PROCMake3D_Sphere(nf%,v(),n(),t(),1,nf%,0.0,0.4,0.01,0.4)
      v()*=0.3
      n()*=0.3
      PROCShift(v(),-1,0,0,nv%)
      PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FFFFFFFF,&FFFFFFFF)

      PROCCloseFVF(f%)
      END
     :
      DEFPROCPoly(n%,starta,cx%,cy%,hr%,vr%,c1%,c2%)
      REM number of sides, start angle in radians, centre x and y, horizontal and vertical radii, main and highlight colours
      LOCAL a%,dx%,dy%
      REM Draw basic shape
      GCOL c1%
      FOR a%=0 TO n%-1
        MOVE cx%,cy%
        dx%=hr%*COS(2*PI*a%/n%+starta)
        dy%=vr%*SIN(2*PI*a%/n%+starta)
        MOVE cx%+dx%,cy%+dy%
        dx%=hr%*COS(2*PI*(a%+1)/n%+starta)
        dy%=vr%*SIN(2*PI*(a%+1)/n%+starta)
        PLOT 85,cx%+dx%,cy%+dy%
      NEXT a%
      REM add radii in highlight colour
      GCOL c2%
      FOR a%=0 TO n%-1
        dx%=hr%*COS(2*PI*a%/n%+starta)
        dy%=vr%*SIN(2*PI*a%/n%+starta)
        LINE cx%,cy%,cx%+dx%,cy%+dy%
      NEXT a%
      REM Draw a front facet half the size
      hr% DIV=2
      vr% DIV=2
      FOR a%=0 TO n%-1
        MOVE cx%,cy%
        dx%=hr%*COS(2*PI*a%/n%+starta)
        dy%=vr%*SIN(2*PI*a%/n%+starta)
        MOVE cx%+dx%,cy%+dy%
        dx%=hr%*COS(2*PI*(a%+1)/n%+starta)
        dy%=vr%*SIN(2*PI*(a%+1)/n%+starta)
        PLOT 85,cx%+dx%,cy%+dy%
      NEXT a%
      ENDPROC
      :
 
User IP Logged

michael
Senior Member
ImageImageImageImage


member is offline

Avatar




PM


Posts: 335
xx Re: The 3D editor tool kit: ideas
« Reply #14 on: Sep 28th, 2017, 03:13am »

Nice work DDRM! And here is the viewer:

TYPE: sword
When it asks for the file name and then when the black screen shows, left click with your mouse..

ALSO: use left mouse button on TOP, RIGHT, LEFT and BOTTOM of screen to rotate the object.

NOTE: this renderer also cycles because it is part of the 3D editor that is still being worked on. (the two window version)


I plan to add another axis of rotation and improve it much more
Code:
      PRINT "USE LEFT MOUSE BUTTON TO ACTIVATE RENDERER AND TO ROTATE THE OBJECT"
      PRINT "Name of FVF image. No need for extension"
      INPUT name$

      peak=0
      IF INKEY$(-256)="W" INSTALL @lib$+"D3DLIBA" ELSE INSTALL @lib$+"OGLLIB"
      pass%=0
      MODE 8
      DIM l%(0), b%(1), n%(1), f%(1), s%(1), m%(1), t%(1), y(1), p(1), r(1), X(1), Y(1), Z(1), e(2), a(2)
      ON CLOSE PROCcleanup:QUIT
      ON ERROR PROCcleanup:PRINT REPORT$:END
      IF INKEY$(-256)="W" d% = FN_initd3d(@hwnd%, 1, 0) ELSE d% = FN_initgl(@hwnd%, 1, 0)
      IF d% = 0 ERROR 100, "Can't initialise Direct3D"
      e() = 0, 0, -6
      a() = 0, 0, 0
      l%()=1
      REPEAT
        REPEAT
          MOUSE mx,my,mb
          IF mx>0 AND my>0 AND mx<1270 AND my<1000 AND mb=4 THEN pass%=1
          WAIT 1
        UNTIL pass%=1
        IF pass%=1 THEN
          IF mx>800 AND my>400 AND my<600 THEN y()+=0.1
          IF mx<400 AND my>400 AND my<600 THEN y()-=0.1
          IF my>600 AND my<1000 THEN p()+=0.1
          IF my<400 AND my>0 THEN p()-=0.1
        ENDIF
        pass%=0
        b%(0) = FN_load3d(d%, @dir$+name$+".FVF", n%(0), f%(0), s%(0))
        IF b%(0) = 0 ERROR 100, "Can't load TRIANGLE.FVF"
        t%(0) = FN_loadtexture(d%, @dir$+"swordtexture.BMP")
        IF t%(0) = 0 ERROR 100, "Can't load face.JPG"
  
  
        REM y() =0:REM yaw (rotations around the Y axis)
        REM pitch
        REM p() =0:REM TIME/100 (pitch angles rotations around the X axis)
        REM roll
        r() = 0:REM TIME/40 (roll angles (rotations around the Z axis)
        REM X (right left)
        X() = 0:REM SIN(TIME/200)
        REM Y() up and down
        Y() = 0
        REM Z() depth
        Z() =  10:REM
  
        REM PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000)
        PROC_render(d%, &FF7F7F7F, 0, l%(), 2, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000, 0) :REM experimental
        REM          1     2       3   4    5   6     7     8     9     10    11   yaw pitch roll X    Y    Z eye0123  18   19   20   ^mcd  ^( cam to farplane dist)
        REM 1 Val returned from FN_init3D
        REM 2 back color   3 #of lights   4 light pointers
        REM t%() - holds texture
        REM mcd - minimum near cam distance
  
        WAIT 1
        t%(1) += 0:IF t%(1) PROC_release(t%(1))
        b%(0) += 0:IF b%(0) PROC_release(b%(0))
        b%(1) += 0:IF b%(1) PROC_release(b%(1))
  
      UNTIL FALSE
      END

      DEF PROCcleanup
      t%(1) += 0:IF t%(1) PROC_release(t%(1))
      b%(0) += 0:IF b%(0) PROC_release(b%(0))
      b%(1) += 0:IF b%(1) PROC_release(b%(1))
      d% += 0   :IF d%    PROC_release(d%)
      ENDPROC
 
« Last Edit: Sep 28th, 2017, 04:18am by michael » User IP Logged

I like making program generators and like reinventing the wheel
Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls