|
Post by choto on Jun 15, 2004 10:18:16 GMT -5
Anybody has a code to a simple viewer of obj wavefront 3d models, or a tutorial to create it, I only need translation, rotation and scale and it is not necesary to read textures, I am lokking only wireframe representation of the obj model.
Thanks.
|
|
|
Post by Vladeta on Jun 15, 2004 12:27:49 GMT -5
Try to convert it to MD2 and import it into Basic4GL. Are you using Maya?
|
|
|
Post by choto on Jun 15, 2004 15:20:47 GMT -5
No, I am nor using maya....
I am trying to make a little tool that use the toxic render engine to render. This render engine use obj files to import geopmetry in it. My tool will have a 3d model library, make by me, an I think if I use obj models in my tool, when I export my tool's scene to toxic scene will be easier. I want to make a little viewer in my tool so the user can make the 3d world settings easier.
I found obj viewer in java an c++, but before transform this viewer to basic4gl, I ask if someone make a viewer before...
|
|
|
Post by Tom Mulgrew on Jun 15, 2004 18:20:46 GMT -5
Part1 (darn 10,000 char limit) ' Wavefront .obj viewer
' Data structures ' ' Data is stored as a list of vertices, containing
struc SOBJ_polyVertex dim vertexIndex dim normIndex endstruc
struc SOBJ_poly dim firstVertex, vertexCount ' Indicates a section of the polyVertex array that makes up the current polygon endstruc
struc SOBJ_model dim vertexCount, &vertex# ()() ' Actual X, Y, Z vertices dim normCount, &norm#()() ' Actual X, Y, Z normals dim polyVertexCount, SOBJ_polyVertex &polyVertex () ' Indices of vertices arranged into polygons dim polyCount, SOBJ_poly &poly () ' Polygon data endstruc ' Variables. ' Passed as parameters to subroutines dim SOBJ_model &theModel, SOBJ_poly &thePoly, theFile, theDir$, theFileName$, SOBJ_polyVertex &thePolyVertex dim &theVec#()
' Working variables dim i, i2, tempToken$, tempChar$, y
' Subroutines goto Start
LoadChar: tempChar$ = ReadChar (theFile) ' Read character if tempChar$ >= "A" and tempChar$ <= "Z" then ' Convert to lowercase tempChar$ = Chr$ (Asc(tempChar$) - Asc("A") + Asc ("a")) endif return
InternalLoadToken: ' Load a text token from file "theFile" ' Same as LoadToken below, but doesn't strip comments tempToken$ = "" if tempChar$ = "" then return endif ' Skip whitespace and format characters (except for chr$(13)) while tempChar$ <> "" and tempChar$ <> chr$(13) and tempChar$ <= " " gosub LoadChar wend if tempChar$ = "" then return endif
' Determine token type from first character tempToken$ = tempChar$ if tempChar$ >= "a" and tempChar$ <= "z" then ' Word ' Read character string gosub LoadChar while tempChar$ >= "a" and tempChar$ <= "z" tempToken$ = tempToken$ + tempChar$ gosub LoadChar wend return endif if tempChar$ >= "0" and tempChar$ <= "9" or tempChar$ = "-" or tempChar$ = "+" or tempChar$ = "." then ' Number ' Read number gosub LoadChar while tempChar$ >= "0" and tempChar$ <= "9" or tempChar$ = "-" or tempChar$ = "+" or tempChar$ = "." or tempChar$ = "e" tempToken$ = tempToken$ + tempChar$ gosub LoadChar wend return endif ' Treat everything else as a single character symbol gosub LoadChar return
LoadToken: ' Load a text token from file "theFile" ' Expects: theFile = An open file handle ' Returns: tempToken$ = "" If end of file reached ' tempToken$ = chr$(13) If end of line reached ' tempToken$ =
' Load a token gosub InternalLoadToken ' Skip comments if tempToken$ = "#" then gosub InternalLoadToken while tempToken$ <> chr$(13) and tempToken$ <> "" gosub InternalLoadToken wend endif return
OpenObjFile: theFile = OpenFileRead (theDir$ + theFileName$) tempChar$ = " " if FileError () <> "" then printr "Error opening " + theDir$ + theFileName$ printr FileError () end endif return
LoadObj:
' Expects: theDir$ = Directory containing file(s) ' theFileName$ = Obj file to load
' File is scanned in 2 passes. ' First pass counts the elements of each type. ' Second loads them ' Open file gosub OpenObjFile ' Allocate model alloc theModel
' First pass: Count printr "Count vertices, polys, normals..." gosub LoadToken while tempToken$ <> "" y = 1: while SyncTimer (500): gosub DisplayCounters: wend if tempToken$ = "v" then
' Count vertex theModel.vertexCount = theModel.vertexCount + 1 endif if tempToken$ = "vn" then ' Count normal theModel.normCount = theModel.normCount + 1 endif
if tempToken$ = "f" then
' Count polygon theModel.polyCount = theModel.polyCount + 1
' Count polygon corners gosub LoadToken while tempToken$ <> "" and tempToken$ <> chr$(13) theModel.polyVertexCount = theModel.polyVertexCount + 1 while tempChar$ <> "" and tempChar$ > " " ' Skip to whitespace gosub LoadChar wend gosub LoadToken wend endif ' Skip to end of line while tempToken$ <> chr$(13) gosub LoadToken wend ' Next token gosub LoadToken wend gosub DisplayCounters
' Allocate vertices and polygons alloc theModel.vertex#, theModel.vertexCount - 1, 2 alloc theModel.norm#, theModel.normCount - 1, 2 alloc theModel.poly, theModel.polyCount - 1 alloc theModel.polyVertex, theModel.polyVertexCount - 1 ' Reset counters theModel.vertexCount = 0 theModel.normCount = 0 theModel.polyCount = 0 theModel.polyVertexCount = 0 ' Second pass. Load data printr "Load model..." CloseFile (theFile) gosub OpenObjFile
gosub LoadToken while tempToken$ <> "" y = 3: while SyncTimer (500): gosub DisplayCounters: wend if tempToken$ = "v" then ' Vector found ' Load in each coordinate y = 1: gosub LoadToken for i = 0 to 2 if tempToken$ <> "" and tempToken$ <> chr$(13) then theModel.vertex# (theModel.vertexCount) (i) = val (tempToken$) gosub LoadToken endif next theModel.vertexCount = theModel.vertexCount + 1
|
|
|
Post by Tom Mulgrew on Jun 15, 2004 18:21:39 GMT -5
part 2. else if tempToken$ = "vn" then ' Normal found ' Load in coordinates gosub LoadToken for i = 0 to 2 if tempToken$ <> "" and tempToken$ <> chr$(13) then theModel.norm# (theModel.normCount) (i) = val (tempToken$) gosub LoadToken endif next theModel.normCount = theModel.normCount + 1 else if tempToken$ = "f" then ' Face found ' Record start of polygon vertices &thePoly = &theModel.poly (theModel.polyCount) theModel.polyCount = theModel.polyCount + 1 thePoly.firstVertex = theModel.polyVertexCount ' Read vertices gosub LoadToken while tempToken$ <> "" and tempToken$ <> chr$(13) theModel.polyVertex (theModel.polyVertexCount).vertexIndex = val (tempToken$) - 1 ' Note: In the file the index is 1 origin. We are using 0 origin, so must subtract 1 ' Vertex data stored in 3 parts, separated by slashes ' Look for second part gosub LoadToken if tempToken$ = "/" then gosub LoadToken ' Second part is texture coordinates which we haven't implemented yet ' So skip it if tempToken$ <> "" and tempToken$ <> chr$(13) and tempToken$ <> "/" then gosub LoadToken endif ' Third part is normal if tempToken$ = "/" then gosub LoadToken if tempToken$ <> "" and tempToken$ <> chr$(13) then theModel.polyVertex (theModel.polyVertexCount).normIndex = val (tempToken$) - 1 endif endif endif
while tempChar$ <> "" and tempChar$ > " " ' Skip to whitespace gosub LoadChar wend gosub LoadToken
theModel.polyVertexCount = theModel.polyVertexCount + 1 wend ' Complete polygon definition thePoly.vertexCount = theModel.polyVertexCount - thePoly.firstVertex endif endif endif ' Skip to end of line while tempToken$ <> chr$(13) gosub LoadToken wend ' Next token gosub LoadToken wend gosub DisplayCounters
CloseFile (theFile) return
DisplayCounters: ' Output vertex and poly counts. (To show we're actually doing something...!) locate 0, y: printr theModel.vertexCount + ", " + theModel.normCount + ", " + theModel.polyCount + ", " + theModel.polyVertexCount return
DrawObj:
' Render obj model ' Expects: theModel = Points to model to render for i = 0 to theModel.polyCount - 1 &thePoly = &theModel.poly (i) glBegin (GL_TRIANGLE_FAN) for i2 = 0 to thePoly.vertexCount - 1 &thePolyVertex = &theModel.polyVertex (thePoly.firstVertex + i2) glNormal3fv (theModel.norm# (thePolyVertex.normIndex)) glVertex3fv (theModel.vertex# (thePolyVertex.vertexIndex)) next glEnd () next return
' Main program Start: ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Test by loading a sample model
dim SOBJ_model &model, xang#, yang#, zoom#, list, key$, saveFileName$
ResizeText (60, 30) theDir$ = "Files\" theFileName$ = "brspy.obj" gosub LoadObj ' Models can have several thousand vertices and polygons, which can cause our ' virtual machine based language to chug a little bit. ' Therefore we render the frame once into a display list, which will usually speed things up dramatically printr "Create display list..." list = glGenLists (1) glNewList (list, GL_COMPILE) gosub DrawObj glEndList () &model = &theModel zoom# = 3 yang# = 90 xang# = 25
' Lighting glEnable (GL_LIGHTING) glEnable (GL_LIGHT0) glEnable (GL_COLOR_MATERIAL) glClearColor (.2, .2, .2, 1) gosub Instructions
' Draw model while true glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) glLoadIdentity () glTranslatef (0, 0, -zoom#) glRotatef (xang#, 1, 0, 0) glRotatef (yang#, 0, 1, 0) glCallList (list) DrawText () SwapBuffers () ' User interface
while SyncTimer (10) ' Arrow keys rotate model if ScanKeyDown (VK_LEFT) then yang# = yang# - 1 endif if ScanKeyDown (VK_RIGHT) then yang# = yang# + 1 endif if ScanKeyDown (VK_UP) then xang# = xang# - 1 endif if ScanKeyDown (VK_DOWN) then xang# = xang# + 1 endif ' Pgup/Pgdn zoom in/out if ScanKeyDOWN (VK_PRIOR) then zoom# = zoom# - .1 endif if ScanKeyDOWN (VK_NEXT) then zoom# = zoom# + .1 endif wend key$ = Inkey$ () if key$ = "S" or key$ = "s" then gosub SaveBGM gosub Instructions endif wend end Instructions: TextMode (TEXT_OVERLAID) cls printr theFileName$ printr "Arrow keys rotate" printr "PgUp/PgDn zooms" return SaveBGM:
' Change extension to bgm if theFileName$ = "" then return endif i = len (theFileName$) saveFileName$ = "" while saveFileName$ = "" if i <= 0 then saveFileName$ = theFileName$ + ".bgm" else if mid$ (theFileName$, i, 1) = "." then saveFileName$ = left$ (theFileName$, i) + "bgm" else if mid$ (theFileName$, i, 1) = "\" then saveFileName$ = theFileName$ + ".bgm" else i = i - 1 endif endif endif wend ' Save in Basic4GL Model format (which I just invented) theFile = OpenFileWrite (theDir$ + saveFileName$) if FileError() <> "" then print "Can't open file " + theDir$ + theFileName$ + " for output" while Inkey$ () <> "": wend while Inkey$ () = "": wend return endif
' Write Vertices WriteInt (theFile, theModel.vertexCount) for i = 0 to theModel.vertexCount - 1 &theVec# = &theModel.vertex#(i) gosub WriteVec ' Normal WriteFloat (theFile, 0) ' Texture coordinate (not implemented yet) WriteFloat (theFile, 0) next ' Write normals WriteInt (theFile, theModel.normCount) for i = 0 to theModel.normCount - 1 &theVec# = &theModel.norm#(i) gosub WriteVec next ' Write poly vertices WriteInt (theFile, theModel.polyVertexCount) for i = 0 to theModel.polyVertexCount - 1 &thePolyVertex = &theModel.polyVertex (i) WriteInt (theFile, thePolyVertex.vertexIndex) WriteInt (theFile, thePolyVertex.normIndex) next ' Write polygons WriteInt (theFile, theModel.polyCount) for i = 0 to theModel.polyCount - 1 &thePoly = &theModel.poly (i) WriteInt (theFile, thePoly.FirstVertex) WriteInt (theFile, thePoly.vertexCount) next CloseFile (theFile) return WriteVec: WriteFloat (theFile, theVec# (0)) WriteFloat (theFile, theVec# (1)) WriteFloat (theFile, theVec# (2)) return
Very simple viewer. Doesn't use all the info that's there. Once viewing, you can hit 'S' to save in bgm format. -Tom
|
|
|
Post by choto on Jun 16, 2004 9:27:07 GMT -5
Ok, thank you very much, I tell you later.... ;D
|
|
|
Post by NoVaGene on Jun 17, 2004 13:47:27 GMT -5
Tom, u r excellent! It seems the zoom# value is too small causing the object to cover the entire window. A value between 100 to 150 looks ok. I've tried creating some objects using a free modeler (anim8or), export to .obj and run your loader... cool! Btw, i realised the .BGM format doesn't have texture section. Is this supported yet?
|
|
|
Post by bigtabs on Jul 5, 2004 6:02:51 GMT -5
How are you guys copy+pasting this? I try to and it just plonks the lot on one line. boo
|
|
|
Post by demo on Oct 11, 2005 13:56:05 GMT -5
yeh how can u not make it on 1 line???
|
|
|
Post by ShadowDust offline on Oct 11, 2005 15:01:25 GMT -5
try coping it to wordpad first
|
|