New version of obj2fvf.bbc

Discussions related to graphics (2D and 3D), animation and games programming
Post Reply
DDRM
Administrator
Posts: 68
Joined: Mon 02 Apr 2018, 18:04

New version of obj2fvf.bbc

Post by DDRM » Mon 10 Sep 2018, 16:41

Some while ago, Richard gave us a program to convert OBJ format 3D files to the FVF format used by D3DLib (for BB4W) and the equivalent OGLLIB (for BBC-SDL). He subsequently found a bug, and has produced an updated version, included below.

You can see the original discussion in the old forum here:

http://www.bbcbasic.co.uk/oldforum/bbcb ... 1505507189

Best wishes,

D

Code: Select all

      REM Wavefront OBJ to FVF converter, Richard Russell, 22-Aug-2018
      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%
        type$ = LEFT$(a$,2)
        a$ = MID$(a$,3)
        CASE type$ 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$)
      LOCAL n
      IF ASCa$=&2F a$ = MID$(a$,2)
      n = VAL(a$)
      WHILE ASCa$=&20 : a$ = MID$(a$,2) : ENDWHILE
      WHILE ASCa$>&20 AND ASCa$<>&2F a$ = MID$(a$,2) : ENDWHILE
      WHILE ASCa$=&20 : a$ = MID$(a$,2) : ENDWHILE
      = n

      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)

DDRM
Administrator
Posts: 68
Joined: Mon 02 Apr 2018, 18:04

Re: New version of obj2fvf.bbc

Post by DDRM » Tue 11 Sep 2018, 08:10

Update: Richard tells me this version will not work for rendering lit textures in BB4W, but will work for BBC-SDL. Update for BB4W in due course...

Best wishes,

D

Post Reply