### New version of obj2fvf.bbc

Posted:

**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

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)
```