Hello all. The below code is modified from the code archives(I believe terabit did it originally). Im trying to get the .obj importer to take normals into consideration when loading. And so far its proving to be a headache. Also the x appended to the front of each function is for use with the XORS 3D Wrapper but it should apply to normal blitz as well. I think it has something to do with the ordering of the normal data.. Im not sure... any mesh guru's care to help?
Type OBJ_VN
Field index%
Field x#, y#, z#
End Type
Type OBJ_VNF
Field v_index%
Field n_index%
End Type
Type OBJ_V
Field index%
Field x#, y#, z#
End Type
Function OBJ_New_VNF(vtx%, vn%)
newVN.OBJ_VNF = New OBJ_VNF
newVN\v_index% = vtx%
newVN\n_index% = vn%
Return
End Function
Function LoadObj(file$, OBJ_USE_TEX=False, Do_centermesh = False)
Local infile, intex$, cmd$, themesh, blanksurf, ek, its
Local P1$, P2$, P3$, P4$, vtx1#, vtx2#, vtx3#, vtx4#
Local tx1#, tx2#, tx3#, tx4#, retmesh, v, uvo
Local vtx = 0
Local vtxn = 0
Local tmp_vn1%, tmp_vn2%, tmp_vn3%, tmp_vn4%
Local OBJ_USING_NORMALS = False
If FileType(file$)=0 Then Return -1
infile = ReadFile(file$)
themesh = xCreateMesh()
tempvert = xCreateMesh()
retmesh = xCreateMesh()
TempVertSurf = xCreateSurface(tempvert)
blanksurf = xCreateSurface(themesh)
While Not Eof(infile)
intex$ = ReadLine$(infile)
cmd$ = ParseEntry(intex$,0)
its = CountIt(intex$," ")
If its>1 Then P1$ = ParseEntry(intex$,1) Else P1$=""
If its>2 Then P2$ = ParseEntry(intex$,2) Else P2$=""
If its>3 Then P3$ = ParseEntry(intex$,3) Else P3$=""
If its>4 Then P4$ = ParseEntry(intex$,4) Else P4$=""
Select cmd$
Case "V"
; Adds vertex to new mesh.
xAddVertex blanksurf,Float(P1$),Float(P2$),Float(P3$)*-1
Case "VT"
; Vertex texture coords.
xAddVertex TempVertSurf,Rand(10),Rand(10),Rand(10)
xVertexTexCoords TempVertSurf,vtx,Float(P1$),1-Float(P2$)
vtx = vtx + 1
Case "VN"
; Get vertex normal from obj
OBJ_USING_NORMALS = True
VN.OBJ_VN = New OBJ_VN
VN\index% = vtxn%
VN\x# = Float(P1$)
VN\y# = Float(P2$)
VN\z# = Float(P3$)
vtxn% = vtxn% + 1
; Case "USEMTL"
Case "F"
If currentsurf = 0 Then
currentsurf = xCreateSurface(retmesh)
EndIf
vtx1# = -65535 : tx1# = -65535
vtx2# = -65535 : tx2# = -65535
vtx3# = -65535 : tx3# = -65535
vtx4# = -65535 : tx4# = -65535
If its>1 Then
ug = CountIt(P1$,"/")
If ug>0 Then
vtx1#=Float(ParseEntry(P1$,0,"/"))-1
EndIf
If ug>1 Then
tx1# = Float(ParseEntry(P1$,1,"/"))-1
EndIf
If ug>2 Then
tmp_vn1% = Int(ParseEntry(P1$,2,"/"));-1
OBJ_New_VNF(Int(vtx1#), tmp_vn1%)
EndIf
EndIf
If its>2 Then
ug = CountIt(P2$,"/")
If ug>0 Then
vtx2#=Float(ParseEntry(P2$,0,"/"))-1
EndIf
If ug>1 Then
tx2# = Float(ParseEntry(P2$,1,"/"))-1
EndIf
If ug>2 Then
tmp_vn2% = Int(ParseEntry(P2$,2,"/"));-1
OBJ_New_VNF(Int(vtx2#), tmp_vn2%)
EndIf
EndIf
If its>3 Then
ug = CountIt(P3$,"/")
If ug>0 Then
vtx3#=Float(ParseEntry(P3$,0,"/"))-1
EndIf
If ug>1 Then
tx3# = Float(ParseEntry(P3$,1,"/"))-1
EndIf
If ug>2 Then
tmp_vn3% = Int(ParseEntry(P3$,2,"/"));-1
OBJ_New_VNF(Int(vtx3#), tmp_vn3%)
EndIf
EndIf
If its>4 Then
ug = CountIt(P4$,"/")
If ug>0 Then
vtx4#=Float(ParseEntry(P4$,0,"/"))-1
EndIf
If ug>1 Then
tx4# = Float(ParseEntry(P4$,1,"/"))-1
EndIf
If ug>2 Then
tmp_vn4% = Int(ParseEntry(P4$,2,"/"));-1
OBJ_New_VNF(Int(vtx4#), tmp_vn4%)
EndIf
EndIf
If vtx1<0 Then vtx1 = 0
If vtx2<0 Then vtx2 = 0
If vtx3<0 Then vtx3 = 0
If vtx4<0 Then vtx4 = 0
If vtx1>xCountVertices(blanksurf)-1 Then vtx1 = xCountVertices(blanksurf)-1
If vtx2>xCountVertices(blanksurf)-1 Then vtx2 = xCountVertices(blanksurf)-1
If vtx3>xCountVertices(blanksurf)-1 Then vtx3 = xCountVertices(blanksurf)-1
If vtx4>xCountVertices(blanksurf)-1 Then vtx4 = xCountVertices(blanksurf)-1
If tx1>xCountVertices(tempvertsurf)-1 Then tx1 = xCountVertices(tempvertsurf)-1
If tx2>xCountVertices(tempvertsurf)-1 Then tx2 = xCountVertices(tempvertsurf)-1
If tx3>xCountVertices(tempvertsurf)-1 Then tx3 = xCountVertices(tempvertsurf)-1
If tx4>xCountVertices(tempvertsurf)-1 Then tx4 = xCountVertices(tempvertsurf)-1
v = xCountVertices(currentsurf)
If its>1 Then
If tx1<0 Then tx1 = tx1 + vtx+1
uvo = tx1
If xCountVertices(TempVertSurf)=0 Then
xAddVertex currentsurf,xVertexX(blanksurf,vtx1),xVertexY(blanksurf,vtx1),xVertexZ(blanksurf,vtx1)
Else
xAddVertex currentsurf,xVertexX(blanksurf,vtx1),xVertexY(blanksurf,vtx1),xVertexZ(blanksurf,vtx1),xVertexU(TempVertSurf,uvo),xVertexV(TempVertSurf,uvo)
EndIf
EndIf
If its>2 Then
If tx2<0 Then tx2 = tx2 + vtx+1
uvo = tx2
If xCountVertices(TempVertSurf)=0 Then
xAddVertex currentsurf,xVertexX(blanksurf,vtx2),xVertexY(blanksurf,vtx2),xVertexZ(blanksurf,vtx2)
Else
xAddVertex currentsurf,xVertexX(blanksurf,vtx2),xVertexY(blanksurf,vtx2),xVertexZ(blanksurf,vtx2),xVertexU(TempVertSurf,uvo),xVertexV(TempVertSurf,uvo)
EndIf
EndIf
If its>3 Then
If tx3<0 Then tx3 = tx3 + vtx+1
uvo = tx3
If xCountVertices(TempVertSurf)=0 Then
xAddVertex currentsurf,xVertexX(blanksurf,vtx3),xVertexY(blanksurf,vtx3),xVertexZ(blanksurf,vtx3)
Else
xAddVertex currentsurf,xVertexX(blanksurf,vtx3),xVertexY(blanksurf,vtx3),xVertexZ(blanksurf,vtx3),xVertexU(TempVertSurf,uvo),xVertexV(TempVertSurf,uvo)
EndIf
EndIf
If its>4 Then
If tx4<0 Then tx4 = tx4 + vtx+1
uvo = tx4
If xCountVertices(TempVertSurf)=0 Then
xAddVertex currentsurf,xVertexX(blanksurf,vtx4),xVertexY(blanksurf,vtx4),xVertexZ(blanksurf,vtx4)
Else
xAddVertex currentsurf,xVertexX(blanksurf,vtx4),xVertexY(blanksurf,vtx4),xVertexZ(blanksurf,vtx4),xVertexU(TempVertSurf,uvo),xVertexV(TempVertSurf,uvo)
EndIf
EndIf
xAddTriangle currentsurf,v,v+1,v+2
If its>4 Then
xAddTriangle currentsurf,v+2,v+3,v
EndIf
End Select
Wend
CloseFile infile
xFlipMesh retmesh
If OBJ_USING_NORMALS = True Then
OBJ_Apply_Normals(retmesh)
Else
xUpdateNormals retmesh
End If
;xUpdateNormals retmesh ; Dont use Update Normals if VN command above made changes to VertexNormal.
Delete Each OBJ_VNF
Delete Each OBJ_VN
xFreeEntity tempvert
xFreeEntity themesh
Return retmesh
End Function
Function OBJ_Apply_Normals(mesh)
on_surf = xCountSurfaces(mesh)
For cur_surf = 0 To on_surf -1
final_surf = xGetSurface(mesh,cur_surf)
For this.OBJ_VNF = Each OBJ_VNF
For VN.OBJ_VN = Each OBJ_VN
If VN\index% = this\n_index% Then
DebugLog "mine!!! " + this\n_index + "\" + VN\x# + ", " + VN\y# + ", " + VN\z#
xVertexNormal(final_surf, this\v_index%, VN\x#, VN\y#, VN\z#)
End If
Next
Next
Next
Return
End Function
Function ParseEntry$( Message$, Item, Sep$ = " ")
Local fas, count, spos, epos, num#, epon#,pos
Repeat
fas = Instr(message$,sep$,fas+1)
count = count + 1
Until fas = 0 Or count = item
spos = fas+1
epos = Instr(message$+sep$,sep$,fas+1)
grub$ = Upper$(Trim$(Mid$(message$,spos,(epos-spos))))
If Instr(grub$,"E-") Then
pos = Instr(grub$,"E-")
;1.41e-02 = 1.41 * (10 ^ -2)
num# = Left$(grub$,pos-1)
epon# = Mid$(grub$,pos+1,Len(grub$)-(pos))
;'DebugLog "Total: "+grub$
;'DebugLog "Num: "+num#
;'DebugLog "etex: "+Mid$(grub$,pos+1,Len(grub$)-(pos))
;'DebugLog "Exp: "+epon#
num# = num# * (10 ^ epon#)
Return num#
Return "0.0"
Else
Return grub$
EndIf
End Function
Function CountIt( Message$, Sep$=" ")
message$=Trim$(message$)
Local fas, count
Repeat
fas = Instr(message$,sep$,fas+1)
If fas<>0 Then count = count + 1
Until fas = 0
Return count+1
End Function
|