/*
http://en.wikipedia.org/wiki/Wavefront_.obj_file
Hunter and Dog Model
http://www.turbosquid.com/3d-models/free-scan-statue-hunter-dog-3d-model/791511
*/
#compact
'#file "t.exe"
% filename "t.exe"
% Title "STL VIEWER (F1 Help F5 Render)"
'% WindowOpacity 240 'max 255
'% Animated
% ScaleUp
'% PlaceCentral
'% AnchorCentral
'% NoEscape
% ColorCodedPick
'
% SymbolTerm 47 '- /' self delimited symbols
includepath "$/inc/"
'include "RTL64.inc"
include "ConsoleG.inc"
include "ParseUtil.inc"
'STRUCTURES
'==========
type Vertex3d float x,y,z
type Vertex4d float x,y,z,w
'
string ObjFilename ' loaded file
string status ' info about file
string er ' info about errors
float smin ' min scalar size (incl negatives)
float smax ' max scalar size
sys minmax ' flag for smin and smax
string d 'BUFFER FOR DATA TEXT
sys i 'SOURCE STRING INDEX
sys p 'SOURCE STRING POINTER
float c
'
macro ReadVal(v)
================
'READ NUMBERS DIRECTLY FROM STL STRING
skiplspace d,i
v=valat p+i
StepWord d,i 'READY FOR NEXT WORD
if minmax then
if v<smin then smin=v
if v>smax then smax=v
end if
end macro
'
sub ReadVertex3D(vertex3d*ve)
=============================
readval ve.x
readval ve.y
'CHECK FOR OPTIONAL VALUE
skiplspace d,i
if ascb>32 then
readval ve.z
else
ve.z=0.0
end if
'ITR OPTIONAL VERTEX COLORS
end sub
'
sub ReadVertex4D(vertex4d*ve)
=============================
readval ve.x
readval ve.y
readval ve.z
'CHECK FOR OPTIONAL VERTEX
skiplspace d,i
if ascb>32 then
readval ve.w
else
ve.w=1.0
end if
'ITR OPTIONAL VERTEX COLORS
end sub
'
macro RenderVertex
==================
@f=pu[k] : if @f then glTexCoord2fv f
@f=pn[k] : if @f then glNormal3fv f
@f=pm[k] : if @f then glVertex3fv f
end macro
'
macro ReadFace()
================
j=1
vj=1
sg=0
do
skiplspace d,i
select ascb
case 0 to 31 : exit do 'END OF LINE
case 45 : sg=1 : i=sttw+1 'MAKE VERTEX INDEX RELATIVE
case 47 : vj++ 'ADDITIONAL INDEX
case 46,48 to 57 : 'NUMBERS
vn=valat p+i
if sg then
vn=vim[vj]-vn+1 'RELATIVE TO ABSOLUTE INDEX
end if
select vj
case 1 : pm[j]=@vtm[vn] : j++
case 2 : pu[j]=@vtu[vn]
case 3 : pn[j]=@vtn[vn]
end select
vi=0
sg=0
end select
if j>5 then 'LIMIT TO QUAD
endline d,i
exit do
else
stepword d,i
end if
end do
j-=1
end macro
'
sub SurfaceNormal(vertex4d*n, sys*pm)
=====================================
'see OpenGlSceneFrame.inc
'assumes triangle points are defined anticlockwise
vector u,v
vector p1 at pm[1]
vector p2 at pm[2]
vector p3 at pm[3]
VectorDiff(u,p1,p2)
VectorDiff(v,p1,p3)
n.x=(u.y*v.z)-(u.z*v.y)
n.y=(u.z*v.x)-(u.x*v.z)
n.z=(u.x*v.y)-(u.y*v.x)
end sub
'
macro RenderFace()
==================
ReadFace
select j
case 3 :
glBegin GL_TRIANGLES
if cn=0 then
SurfaceNormal vfn,pm
@f=@vfn : glNormal3fv f
end if
for k=1 to 3
RenderVertex
next
glEnd
case 4 :
glBegin GL_QUADS
if cn=0 then
SurfaceNormal vfn,pm
@f=@vfn : glNormal3fv f
end if
for k=1 to 4
RenderVertex
next
glEnd
case else :
'ITR NOT SUPPORTED
end select
end macro
'
macro ignore()
==============
:
end macro
'
macro CountData()
=================
i=1
le=len d
cm=0 : cu=0 : cn=0 : cp=0 : cf=0
do
StepWord d,i
if i>=le then exit do 'NO MORE WORDS
select ascb
case "v"
@b=p+sttw+1
select b
case "#" : 'SKIP COMMENT
case 9,32 : cm++
case "t" : cu++
case "n" : cn++
case "p" : cp++
end select
case "f" : cf++ 'COLLECT OR PASS TO OPENGL
end select
EndLine d,i
end do
end macro
'
macro ReadLines()
=================
i=1
smin=0 : smax=0
do
StepWord d,i
if i>=le then exit do 'NO MORE WORDS
select ascb
case "v"
@b=p+sttw+1
select b
case "#" : ignore 'SKIP COMMENT
case 9,32 : minmax=1 :
: vim[1]++ : ReadVertex4D vtm[vim[1]]
: minmax=0
case "t" : vim[2]++ : ReadVertex3D vtu[vim[2]]
case "n" : vim[3]++ : ReadVertex4D vtn[vim[3]]
case "p" : vim[4]++ : ReadVertex4D vtp[vim[4]]
end select
case "f" : RenderFace : 'COLLECT OR PASS TO OPENGL
case "m" : ignore 'mtllib
case "u" : ignore 'usemtl
case "o" : ignore 'OBJECTS
case "g" : ignore 'GROUPS
end select
EndLine d,i
end do
end macro
'
macro FreeBuffers()
===================
if @vtm then FreeMemory @vtm
if @vtu then FreeMemory @vtu
if @vtn then FreeMemory @vtn
if @vtp then FreeMemory @vtp
end macro
'
macro NewBuffers()
==================
FreeBuffers
@vtm = GetMemory cm*sizeof(Vertex4D)
@vtu = GetMemory cu*sizeof(Vertex3D)
@vtn = GetMemory cn*sizeof(Vertex4D)
@vtn = GetMemory cp*sizeof(Vertex4D)
end macro
'
function RenderObj()
====================
'
sys j,k 'INDEXES AND ITERATORS
sys m,n,q 'GENERIC
sys sg 'NEG SIGN FLAG FOR RELATIVE VERTEX INDEX
sys vj 'VERTEX ARRAY SELECTOR
sys vn 'VERTEX INDEX
float *f 'FOR GL DATA POINTER
float v 'GENERIC
byte *b 'SOURCE STRING BYTE READER
sys pm[4] 'POINTER TO VERTEX
sys pn[4] 'POINTER TO NORMAL
sys pp[4] 'POINTER TO PARAMETRIC VECTOR / ITR
sys pu[4] 'POINTER TO TEX COORD
sys vim[3] 'MAX VERTEX COUNT FOR MAINS,TEXTURES,NORMALS
sys cf,cm,cu,cn,cp 'COUNTERS
sys t1,t2 'TIMERS
'
t1=GetTickCount
'
Vertex4d vfn 'DEFAULT FACE NORMAL
Vertex4d *vtm 'FOR GLVERTEX
Vertex3d *vtu 'FOR GLTEXCOORD
Vertex4d *vtn 'FOR GLNORMAL
Vertex4d *vtp 'FOR PARAMETRIC VECTOR
'
GetFile ObjFileName,d
le=len d
if not le then
er="Problem accessing file " ObjFileName
jmp fwd done
end if
p=strptr(d)-1
@b=p 'SOURCE BYTES
CountData
string sp=" " ' or tab
if not cf then
jmp fwd done
end if
NewBuffers
ReadLines
FreeBuffers
done:
t2=GetTickCount
status= _
"Faces: " sp cf sp _
"Vert: " sp cm sp _
"Tex: " sp cu sp _
"Norm: " sp cn sp _
"Scalar:" sp str(smax-smin,4) sp _
"mSec:" sp str(t2-t1) sp _
""
if er then status=er
er=""
end function
'
function BuildForm(sys fun) as sys
'=================================
'
'FOR SINGLE OBJECT IN ONE LIST
'
static sys list
if not fun then return 0
list = CompileList list
call fun
glEndList
return list
end function
function main()
===============
'
static sys shape
static string inputs="hunter.obj"
cls 0,0.20,0.20
picksetup
shading
pushstate
static MoveableObject mover
if not mover.id then
mover.set 0x10000,0,0,0,0
mover.a.y =180
mover.aa.y=180
end if
sys dt=15
move dt,-dt*1.5,-dt -1
mover.act
'GoldMaterial.act
'SilverMaterial.act
'RedShinyMaterial.act
WhiteShinyMaterial.act
'go sphere
float f=smax-smin
if f then scale 1.25*dt/f
'scale 1,1,-1.0 'REVERSE Z
go shape
popstate
'
'LINE INPUT
'
flat
PushState
color .20,.80,.00,.88
Scale 1.0
print "File: "
color .80,.80,.00,.88
a=input inputs
if key(0x74) 'F5
Objfilename=inputs
shape=BuildForm(@RenderObj)
key(0x74)=0 'single shot
end if
scale .75
printl status
PopState
printl
printl
printl
'
'
shading 'opposite of flat
'
'
'F1 HELP
'
if key[0x70]
flat
pushstate
move 20,0
color .9,.9,.9
scale 1.5,1.0
printl "Active Keys:"
printl
scale 1/1.5,1.0
printl "Esc" tab "Exit"
printl "Ctrl-P" tab "Take snapshot"
printl "F1 This help panel"
printl "F5 Exec function"
printl
scale 1.5,1.0
printl "Mouse:"
scale 1/1.5,1.0
printl "Point to Object, then"
printl "Left button to Rotate"
printl "Right button to Move"
popstate
end if
picklabel 0
lastkey=0
lastchar=0
end function
EndScript