BBC BASIC
« Wavefront OBJ to FVF converter »

Welcome Guest. Please Login or Register.
Jan 20th, 2018, 4:19pm


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Wavefront OBJ to FVF converter  (Read 329 times)
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Wavefront OBJ to FVF converter
« Thread started on: Sep 15th, 2017, 8:26pm »

I was fascinated by the 3D Face Reconstruction work by the University of Nottingham and wanted to experiment with manipulating the generated 3D models in BBC BASIC. These models are downloadable as Wavefront OBJ format files, whereas of course BBC BASIC expects a Flexible Vertex Format (FVF) file; so I wrote a converter (listed below)! You can see the rather spooky result at the Facebook page.

Here's another automatic conversion from Wavefront OBJ format. The original file is downloadable as trumpet.obj; it has 11,908 nodes and 11,362 polygonal faces of order up to 36.



Another use for the converter would be to take advantage of the 3D editing capabilities of a tool such as MeshLab which can export OBJ files.

Richard.

Code:
      REM Wavefront OBJ to FVF converter, Richard Russell, 15-Sep-2017
      HIMEM = PAGE + 20000000

      ObjFile$ = "trumpet.obj"
      ObjFile% = OPENIN(ObjFile$)
      IF ObjFile%=0 ERROR 100, "Can't open file " + ObjFile$

      IF RIGHT$(ObjFile$,4)=".obj" OR RIGHT$(ObjFile$,4)=".OBJ" THEN
        FVFfile$ = LEFT$(ObjFile$,LEN(ObjFile$)-4) + ".fvf"
      ELSE
        FVFfile$ = ObjFile$ + ".obj"
      ENDIF
      FVFfile% = OPENOUT(FVFfile$)
      IF FVFfile%=0 ERROR 100, "Can't create file " + FVFfile$
      PTR#FVFfile% = 8

      DIM c(100000,2), v(100000,2), t(100000,1), n(100000,2), p(2)

      nv% = 0    : REM Number of vertices
      nt% = 0    : REM Number of texture coordinates
      nn% = 0    : REM Number of normals
      nf% = 0    : REM Number of triangular faces
      vf% = &012 : REM Initial vertex format
      xsum = 0
      ysum = 0
      zsum = 0

      WHILE NOT EOF#ObjFile%
        a$ = GET$#ObjFile%
        CASE LEFT$(a$,2) OF
          WHEN "v ":
            v(nv%,0) = FNn(a$) : v(nv%,1) = FNn(a$) : v(nv%,2) = FNn(a$)
            c(nv%,0) = FNn(a$) : c(nv%,1) = FNn(a$) : c(nv%,2) = FNn(a$)
            IF c(nv%,1) <> 0 OR c(nv%,2) <> 0 vf% OR= &040 : REM Include diffuse colour
            nv% += 1
          WHEN "vt":
            t(nt%,0) = FNn(a$) : t(nt%,1) = FNn(a$)
            IF t(nv%,0) <> 0 OR t(nv%,1) <> 0 vf% OR= &100 : REM Include texture coords
            nt% += 1
          WHEN "vn":
            n(nn%,0) = FNn(a$) : n(nn%,1) = FNn(a$) : n(nn%,2) = FNn(a$)
            nn% += 1
          WHEN "f ":
            t1% = 0 : t2% = 0 : t3% = 0 : n1% = 0 : n2% = 0 : n3% = 0
            v1% = FNn(a$) : IF ASCa$=&2F t1% = FNn(a$) : IF ASCa$=&2F n1% = FNn(a$)
            v2% = FNn(a$) : IF ASCa$=&2F t2% = FNn(a$) : IF ASCa$=&2F n2% = FNn(a$)
            IF v1% > 0 v1% -= 1 ELSE v1% += nv%
            IF v2% > 0 v2% -= 1 ELSE v2% += nv%
            IF t1% > 0 t1% -= 1 ELSE t1% += nt%
            IF t2% > 0 t2% -= 1 ELSE t2% += nt%
            IF n1% > 0 n1% -= 1 ELSE n1% += nn%
            IF n2% > 0 n2% -= 1 ELSE n2% += nn%
            REPEAT
              v3% = FNn(a$) : IF ASCa$=&2F t3% = FNn(a$) : IF ASCa$=&2F n3% = FNn(a$)
              IF v3% = 0 EXIT REPEAT

              IF v3% > 0 v3% -= 1 ELSE v3% += nv%
              IF t3% > 0 t3% -= 1 ELSE t3% += nt%
              IF n3% > 0 n3% -= 1 ELSE n3% += nn%

              REM Vertex coordinates:
              x1 = v(v1%,0) : y1 = v(v1%,1) : z1 = v(v1%,2)
              x2 = v(v2%,0) : y2 = v(v2%,1) : z2 = v(v2%,2)
              x3 = v(v3%,0) : y3 = v(v3%,1) : z3 = v(v3%,2)

              REM Vertex colour:
              R1 = c(v1%,0) : G1 = c(v1%,1) : B1 = c(v1%,2)
              R2 = c(v2%,0) : G2 = c(v2%,1) : B2 = c(v2%,2)
              R3 = c(v3%,0) : G3 = c(v3%,1) : B3 = c(v3%,2)

              REM Texture coordinates:
              u1 = t(t1%,0) : v1 = t(t1%,1)
              u2 = t(t2%,0) : v2 = t(t2%,1)
              u3 = t(t3%,0) : v3 = t(t3%,1)

              REM Normals:
              IF n1% IF n2% IF n3% THEN
                p1 = 0 : q1 = 0 : r1 = 0
                p2 = 0 : q2 = 0 : r2 = 0
                p3 = 0 : q3 = 0 : r3 = 0
                ON ERROR LOCAL IF FALSE THEN
                  p(0) = n(n1%,0) : p(1) = n(n1%,1) : p(2) = n(n1%,2)
                  p() /= MOD(p()) : p1 = p(0) : q1 = p(1) : r1 = p(2)
                  p(0) = n(n2%,0) : p(1) = n(n2%,1) : p(2) = n(n2%,2)
                  p() /= MOD(p()) : p2 = p(0) : q2 = p(1) : r2 = p(2)
                  p(0) = n(n3%,0) : p(1) = n(n3%,1) : p(2) = n(n3%,2)
                  p() /= MOD(p()) : p3 = p(0) : q3 = p(1) : r3 = p(2)
                ENDIF : RESTORE ERROR
              ELSE
                a = x3 - x2
                b = y3 - y2
                c = z3 - z2
                d = x1 - x3
                e = y1 - y3
                f = z1 - z3
                p(0) = b*f-c*e
                p(1) = c*d-a*f
                p(2) = a*e-b*d
                IF MOD(p()) <> 0 p() /= MOD(p())
                p1 = p(0) : q1 = p(1) : r1 = p(2)
                p2 = p(0) : q2 = p(1) : r2 = p(2)
                p3 = p(0) : q3 = p(1) : r3 = p(2)
              ENDIF

              PROC4(FVFfile%,FN4(x1)) : PROC4(FVFfile%,FN4(y1)) : PROC4(FVFfile%,FN4(z1))
              PROC4(FVFfile%,FN4(p1)) : PROC4(FVFfile%,FN4(q1)) : PROC4(FVFfile%,FN4(r1))
              IF vf% AND &040 THEN
                BPUT#FVFfile%,B1*&FF
                BPUT#FVFfile%,G1*&FF
                BPUT#FVFfile%,R1*&FF
                BPUT#FVFfile%,&FF
              ENDIF
              IF vf% AND &100 PROC4(FVFfile%,FN4(u1)) : PROC4(FVFfile%,FN4(v1))

              PROC4(FVFfile%,FN4(x2)) : PROC4(FVFfile%,FN4(y2)) : PROC4(FVFfile%,FN4(z2))
              PROC4(FVFfile%,FN4(p2)) : PROC4(FVFfile%,FN4(q2)) : PROC4(FVFfile%,FN4(r2))
              IF vf% AND &040 THEN
                BPUT#FVFfile%,B2*&FF
                BPUT#FVFfile%,G2*&FF
                BPUT#FVFfile%,R2*&FF
                BPUT#FVFfile%,&FF
              ENDIF
              IF vf% AND &100 PROC4(FVFfile%,FN4(u2)) : PROC4(FVFfile%,FN4(v2))

              PROC4(FVFfile%,FN4(x3)) : PROC4(FVFfile%,FN4(y3)) : PROC4(FVFfile%,FN4(z3))
              PROC4(FVFfile%,FN4(p3)) : PROC4(FVFfile%,FN4(q3)) : PROC4(FVFfile%,FN4(r3))
              IF vf% AND &040 THEN
                BPUT#FVFfile%,B3*&FF
                BPUT#FVFfile%,G3*&FF
                BPUT#FVFfile%,R3*&FF
                BPUT#FVFfile%,&FF
              ENDIF
              IF vf% AND &100 PROC4(FVFfile%,FN4(u3)) : PROC4(FVFfile%,FN4(v3))

              xsum += x1 + x2 + x3
              ysum += y1 + y2 + y3
              zsum += z1 + z2 + z3
              nf% += 1

              v2% = v3% : t2% = t3% : n2% = n3%
            UNTIL FALSE
        ENDCASE
      ENDWHILE
      CLOSE #ObjFile%

      PRINT "Total number of vertices = "; nv%
      PRINT "Total number of texture coordinates = "; nt%
      PRINT "Total number of normals = "; nn%
      PRINT "Total number of faces = "; nf%
      PRINT "Mean X = "; xsum / nf% / 3
      PRINT "Mean Y = "; ysum / nf% / 3
      PRINT "Mean Z = "; zsum / nf% / 3

      vs% = 24 : REM Vertex size (bytes)
      IF vf% AND &040 vs% += 4
      IF vf% AND &100 vs% += 8

      PTR#FVFfile% = 0
      PROC4(FVFfile%, nf%*3)
      PROC4(FVFfile%, vf% OR vs% << 16)
      CLOSE #FVFfile%

      PRINT "Output file '"; FVFfile$; "' created"
      END

      DEF FNn(RETURN a$)
      IF ASCa$=&2F a$ = MID$(a$,2) : = VAL(a$)
      WHILE ASCa$>&20 : a$ = MID$(a$,2) : ENDWHILE
      WHILE ASCa$=&20 : a$ = MID$(a$,2) : ENDWHILE
      = VAL(a$)

      DEF PROC4(F%,N%)
      BPUT#F%,N% : BPUT#F%,N%>>8 : BPUT#F%,N%>>16 : BPUT#F%,N%>>24
      ENDPROC

      DEF FN4(a#)LOCALP%:P%=^a#:IFa#=FALSE THEN=FALSE
      =P%!4ANDNOT&7FFFFFFFOR(P%!4-&38000000<<3OR!P%>>29AND7)+(!P%>>28AND1) 
« Last Edit: Sep 15th, 2017, 10:26pm by Richard Russell » User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Wavefront OBJ to FVF converter
« Reply #1 on: Sep 16th, 2017, 01:15am »

Do you have a converter for OBJ to B3D file? This would be handy since I do have Hexagon 3D and it creates OBJ files.
User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Wavefront OBJ to FVF converter
« Reply #2 on: Sep 16th, 2017, 09:30am »

on Sep 16th, 2017, 01:15am, michael wrote:
Do you have a converter for OBJ to B3D file?

What do you mean by a B3D file? That extension normally refers to a Blitz 3D file (used by Blitz BASIC) which has nothing to do with BBC BASIC. I accidentally used the same extension in the early days for 3D files used by BBC BASIC, but that caused great confusion: the formats have nothing in common.

So now I always use the extension FVF (flexible vertex format) for the 3D files accepted by FN_load3D in D3DLIB(A), OGLLIB and GLESLIB, i.e. the file format described here. You should already be aware of that, because you know that BB4W and BBCSDL are highly compatible in their 3D functionality, which is why Rubik.bbc for example runs equally well in either version without modification.

To avoid perpetuating the confusion please use the extension FVF rather than B3D for BBC BASIC's 3D files. My OBJ to FVF converter creates the right kind of file for use with BB4W and BBCSDL, of course! I'm not stupid, well not totally stupid, well.... undecided

Richard.
User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Wavefront OBJ to FVF converter
« Reply #3 on: Sep 16th, 2017, 12:06pm »

I am quite surprised.

Both me and DDRM have been using this code from your lessons located in:

HELP
table of contents
Graphics
Pyramid-Direct3Dlibrary

And its what you and I have been working on this board earlier when I asked for help.

The lessons are inside BBC Basic For Windows (full version 6.10a). I can see now that FVF has similar code. Ill look at the code you linked.

Code:
F% = OPENOUT"TRIANGLE.B3D"
PROC4(3):REM 3 vertices
PROC4(&100042):REM vertex size &10 and format &42
PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF)
PROC4(FN_f4(1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF00FF00)
PROC4(FN_f4(0.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(0.0)):PROC4(&FFFF0000)
CLOSE #F%
DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC

 
« Last Edit: Sep 16th, 2017, 12:17pm by michael » User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Wavefront OBJ to FVF converter
« Reply #4 on: Sep 16th, 2017, 1:15pm »

on Sep 16th, 2017, 12:06pm, michael wrote:
I am quite surprised. Both me and DDRM have been using this code from your lessons

As you should know, BB4W is supplied with the files BASE.B3D and PYRAMID.B3D (in the EXAMPLES\GRAPHICS folder) so everybody ends up with those files on their disk and I can't make them 'disappear'! Even if I were to change their names in the BB4W distribution, the new files would be stored in addition to the old ones rather than replacing them.

So my judgement was that little would be achieved, other than perhaps even more confusion, by retrospectively changing the extension of the files supplied with BB4W. However you should find that I have consistently used the FVF extension in the context of BBCSDL, so for example the equivalent files supplied with that product are base.fvf and pyramid.fvf. They are the same files, just renamed.

I thought I had made it perfectly clear that the 3D libraries for BBCSDL - ogllib.bbc and gleslib.bbc - are designed to be as compatible as possible with D3DLIBA. That was after all the whole point: to make writing cross-platform programs as painless an exercise as possible (the main residual incompatibility being that the BBCSDL libraries will only accept textures in BMP format). As I said in my previous message, Rubik.bbc runs on both BB4W and BBCSDL without any modification.

Therefore I don't really understand how you came to the conclusion that the (BB4W) B3D and FVF file formats are different. What is certainly the case is that the original Blitz3D variety of B3D file is still in common use and you can find many examples online. There was even a post made to a Blitz forum pointing out (incorrectly) that BB4W uses the same file format. The potential for confusion was far too great for it to be allowed to continue.

I cannot comment on the decision of the admin of the 'other' BB4W forum to continue to use the B3D extension. Perhaps he feels that the FVF extension is associated with BBCSDL, which neither he nor his forum supports.

Richard.
User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Wavefront OBJ to FVF converter
« Reply #5 on: Sep 16th, 2017, 1:22pm »

Richard, it isn't the files that are at issue. The HELP section in BBC4W, when accessing direct 3D uses the B3D format.
I am sure it was just overlooked by DDRM as it wasn't the focus of the goal to make the tools.

I can focus on the FVF extension if there is an issue concerning the other extension. Like with languages, I doubt that a file format can cause issues, aside from giving attention to the other Basic platform.

BBC Basic is far easier than the other language you mentioned.

Also I must say, your work on that converter is a fantastic creation. I have been looking for an OBJ converter for basic for years. (since around 2009

And it really is no big issue, as I see that the code you supplied for FVF and B3D examples are identical:

Code:
      DEF PROCcreate3d
      F% = OPENOUT"TRIANGLE.B3D"
      PROC4(3):REM 3 vertices
      PROC4(&100042):REM vertex size &10 and format &42
      REM       LL x            LL y            LL z             LL colour
      PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF)
      REM       LR x            LR y            LR z            LR colour
      PROC4(FN_f4(1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF00FF00)
      REM     PEAK X     PEAK Y             PEAK Z              Peak colour
      PROC4(FN_f4(0.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(0.0)):PROC4(&FFFF0000)
      CLOSE #F%
      ENDPROC
      :
      DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC

 

Code:
      F% = OPENOUT"TRIANGLE.FVF"
      PROC4(3):REM 3 vertices
      PROC4(&100042):REM vertex size &10 and format &42
      PROC4(FN_f4(-1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF0000FF)
      PROC4(FN_f4(1.0)):PROC4(FN_f4(-1.0)):PROC4(FN_f4(1.0)):PROC4(&FF00FF00)
      PROC4(FN_f4(0.0)):PROC4(FN_f4(1.0)):PROC4(FN_f4(0.0)):PROC4(&FFFF0000)
      CLOSE #F%
      DEF PROC4(A%):BPUT#F%,A%:BPUT#F%,A%>>8:BPUT#F%,A%>>16:BPUT#F%,A%>>24:ENDPROC
 
« Last Edit: Sep 16th, 2017, 1:45pm by michael » User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Wavefront OBJ to FVF converter
« Reply #6 on: Sep 16th, 2017, 1:45pm »

on Sep 16th, 2017, 1:22pm, michael wrote:
Richard, it isn't the files that are at issue. The HELP section in BBC4W, when accessing direct 3D uses the B3D format.

There is no such thing as "B3D format" (or, if you prefer to look at it this way, it's the format of Blitz 3D object files which isn't used by BBC BASIC). Admittedly the code example in the Help file creates a file with the .B3D extension but it's not the extension that defines the file's contents - it's how you create the file! The extension could be anything at all and it would still work.

I don't see what I could have done differently, other than not making the (stupid) mistake of misusing the B3D extension in the first place. Obviously I hugely regret that mistake, as I do the many other stupid decisions that I made when originally creating BB4W. It's one reason why it would have been far better if BBC BASIC for Windows had never existed.

But I did make those mistakes and it's something I have to live with every day (or perhaps not live with, and that's an option I consider every day too). All I can do now is to attempt to put things right as far as possible by no longer using the misleading B3D extension, but you seem to think that is yet another mistake. Argggh!!!!

Richard.
« Last Edit: Sep 16th, 2017, 1:47pm by Richard Russell » User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Wavefront OBJ to FVF converter
« Reply #7 on: Sep 16th, 2017, 1:57pm »

Quote:
but you seem to think that is yet another mistake


Its not a mistake. (you shouldn't have had to change the extension) It was a coincidence.

Everything is ok.

I wish I could be at your skill level. And BBC4W is a fine product.

« Last Edit: Sep 16th, 2017, 2:22pm by michael » User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Wavefront OBJ to FVF converter
« Reply #8 on: Sep 16th, 2017, 4:29pm »

on Sep 16th, 2017, 1:57pm, michael wrote:
It was a coincidence.

I can't claim that excuse. Before adopting the B3D extension I should have looked it up on a site like filext.com (quite different then from what it is now) when I would have discovered its existing use(s).

Richard.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Wavefront OBJ to FVF converter
« Reply #9 on: Sep 17th, 2017, 09:06am »

Has anybody else tried the Nottingham University 3D Face Reconstruction tool? It's very easy to use:
  1. Find a full-face straight-on selfie (preferably without glasses), with good contrast between your face and the background, and upload it here.

  2. When it has finished processing, download the generated .OBJ file and convert it to a .FVF using the code I listed previously in this thread.

  3. Plug the FVF file into the program below if you want to use the same animation as I did for Donald Trump, or adapt it to your preference.

  4. Upload a video capture to YouTube (etc.), so we can see the result, if you dare!
Richard.

Code:
      REM. Turning Face by Richard Russell, 16-Sep-2017

      HIMEM = PAGE + 5000000
      IF INKEY$(-256)="W" INSTALL @lib$+"D3DLIBA" ELSE INSTALL @lib$+"ogllib"

      ON CLOSE PROCcleanup : QUIT
      ON ERROR PROCcleanup : IF ERR=17 CHAIN @lib$+"../examples/tools/touchide" ELSE MODE 3 : PRINT REPORT$ : END
      ON MOVE IF @msg% <> 5 RETURN ELSE PROCcleanup : CLEAR
      VDU 20,26,12

      DIM pVB%(0), nv%(0), vf%(0), vl%(0), l%(0), m%(0), t%(0), y(0), p(0), r(0)
      DIM X(0), Y(0), Z(0), eye(2), at(2)

      REM. Initialise OpenGL:
      IF INKEY$(-256)="W" pDev% = FN_initd3d(@hwnd%, 1, 0) ELSE pDev% = FN_initgl(@hwnd%, 1, 0)
      IF pDev% = 0 ERROR 100, "Couldn't initialise 3D subsystem"

      REM. Load 3D object:
      pVB%(0) = FN_load3d(pDev%, @dir$ + "trump.fvf", nv%(0), vf%(0), vl%(0))
      IF pVB%(0) = 0 ERROR 101, "Couldn't load FVF file"

      REM. Render the turning face:
      at() = 100, 100, 40
      REPEAT
        turn = SIN(TIME/100)
        eye() = at(0)+400*SIN(turn), 0, at(2)+400*COS(turn)
        PROC_render(pDev%, &7F7F90, 0, l%(), 1, m%(), t%(), pVB%(), nv%(), vf%(), vl%(), \
        \ y(), p(), r(), X(), Y(), Z(), eye(), at(), PI/6, @vdu%!208/@vdu%!212, 1, 1000, PI)
      UNTIL INKEY(1)=0
      END

      DEF PROCcleanup
      pVB%(0) += 0  : IF pVB%(0)  PROC_release(pVB%(0))
      *REFRESH ON
      ENDPROC 

« Last Edit: Sep 17th, 2017, 6:05pm by Richard Russell » User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls