Author Topic: Wavefront object viewer  (Read 78996 times)

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

  • Guest
Wavefront object viewer
« on: January 22, 2015, 10:30:58 AM »
The whole project has been moved to its own dedicated server here.

...



« Last Edit: January 25, 2016, 05:48:47 AM by Patrice Terrier »

Frankolinox

  • Guest
Re: Wavefront object viewer
« Reply #1 on: January 23, 2015, 01:34:17 AM »
thank you patrice I will check it next days.. and perhaps I will get an idea to load wavefront object data with oxygen too :)

I've translated over the last years some (more winapi/gui + openGL) examples from powerbasic to oxygenbasic and I was wondering why it's not possible to load *.MTL files  with oxygen that's my intention for next weeks/month..

regards, frank

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #2 on: January 24, 2015, 04:11:10 AM »
Thanks again, Patrice.

Work in progress:  :)

Code: OxygenBasic
  1. /*
  2.  
  3.   http://en.wikipedia.org/wiki/Wavefront_.obj_file
  4.  
  5.   Hunter and Dog Model
  6.   http://www.turbosquid.com/3d-models/free-scan-statue-hunter-dog-3d-model/791511
  7.  
  8. */
  9.  
  10.   #compact
  11.  '#file "t.exe"
  12.  % filename "t.exe"
  13.   % Title "STL VIEWER (F1 Help  F5 Render)"
  14.  '% WindowOpacity 240 'max 255
  15. '% Animated
  16.  % ScaleUp
  17.  '% PlaceCentral
  18. '% AnchorCentral
  19. '% NoEscape
  20.  % ColorCodedPick
  21.   '
  22.  % SymbolTerm 47 '- /' self delimited symbols
  23.  
  24.   includepath "$/inc/"
  25.  'include     "RTL64.inc"
  26.  include     "ConsoleG.inc"
  27.   include     "ParseUtil.inc"
  28.  
  29.   'STRUCTURES
  30.  '==========
  31.  type Vertex3d float x,y,z
  32.   type Vertex4d float x,y,z,w
  33.   '
  34.  string ObjFilename ' loaded file
  35.  string status      ' info about file
  36.  string er          ' info about errors
  37.  float  smin        ' min scalar size (incl negatives)
  38.  float  smax        ' max scalar size
  39.  sys    minmax      ' flag for smin and smax
  40.  string d           'BUFFER FOR DATA TEXT
  41.  sys    i           'SOURCE STRING INDEX
  42.  sys    p           'SOURCE STRING POINTER
  43.  float  c
  44.   '
  45.  macro ReadVal(v)
  46.   ================
  47.   'READ NUMBERS DIRECTLY FROM STL STRING
  48.  skiplspace d,i
  49.   v=valat p+i
  50.   StepWord d,i 'READY FOR NEXT WORD
  51.  if minmax then
  52.     if v<smin then smin=v
  53.     if v>smax then smax=v
  54.   end if
  55.   end macro
  56.   '
  57.  sub ReadVertex3D(vertex3d*ve)
  58.   =============================
  59.   readval ve.x
  60.   readval ve.y
  61.   'CHECK FOR OPTIONAL VALUE
  62.  skiplspace d,i
  63.   if ascb>32 then
  64.     readval ve.z
  65.   else
  66.     ve.z=0.0
  67.   end if
  68.   'ITR OPTIONAL VERTEX COLORS
  69.   end sub              
  70.   '
  71.  sub ReadVertex4D(vertex4d*ve)
  72.   =============================
  73.   readval ve.x
  74.   readval ve.y
  75.   readval ve.z
  76.   'CHECK FOR OPTIONAL VERTEX
  77.  skiplspace d,i
  78.   if ascb>32 then
  79.     readval ve.w
  80.   else
  81.     ve.w=1.0
  82.   end if
  83.   'ITR OPTIONAL VERTEX COLORS
  84.  end sub
  85.   '
  86.  macro RenderVertex
  87.   ==================
  88.   @f=pu[k] : if @f then glTexCoord2fv f
  89.   @f=pn[k] : if @f then glNormal3fv   f
  90.   @f=pm[k] : if @f then glVertex3fv   f
  91.   end macro
  92.   '
  93.  macro ReadFace()
  94.   ================
  95.   j=1
  96.   vj=1
  97.   sg=0
  98.   do
  99.     skiplspace d,i
  100.     select ascb
  101.     case 0  to 31 : exit do 'END OF LINE
  102.    case 45       : sg=1 : i=sttw+1    'MAKE VERTEX INDEX RELATIVE
  103.    case 47       : vj++    'ADDITIONAL INDEX
  104.    case 46,48 to 57 :      'NUMBERS
  105.      vn=valat p+i
  106.       if sg then
  107.         vn=vim[vj]-vn+1 'RELATIVE TO ABSOLUTE INDEX
  108.      end if
  109.       select vj
  110.       case 1 : pm[j]=@vtm[vn] : j++
  111.       case 2 : pu[j]=@vtu[vn]
  112.       case 3 : pn[j]=@vtn[vn]
  113.       end select
  114.       vi=0
  115.       sg=0
  116.     end select
  117.     if j>5 then 'LIMIT TO QUAD
  118.      endline d,i
  119.       exit do
  120.     else
  121.       stepword d,i
  122.     end if
  123.   end do
  124.   j-=1
  125.   end macro
  126.   '
  127.  sub SurfaceNormal(vertex4d*n, sys*pm)
  128.   =====================================
  129.   'see OpenGlSceneFrame.inc
  130.  'assumes triangle points are defined anticlockwise
  131.  vector u,v
  132.   vector p1 at pm[1]
  133.   vector p2 at pm[2]
  134.   vector p3 at pm[3]
  135.   VectorDiff(u,p1,p2)
  136.   VectorDiff(v,p1,p3)
  137.   n.x=(u.y*v.z)-(u.z*v.y)
  138.   n.y=(u.z*v.x)-(u.x*v.z)
  139.   n.z=(u.x*v.y)-(u.y*v.x)
  140.   end sub
  141.   '
  142.  macro RenderFace()
  143.   ==================
  144.   ReadFace
  145.   select j
  146.   case 3  :
  147.     glBegin GL_TRIANGLES
  148.     if cn=0 then
  149.       SurfaceNormal vfn,pm
  150.       @f=@vfn : glNormal3fv f
  151.     end if
  152.     for k=1 to 3
  153.       RenderVertex
  154.     next
  155.     glEnd
  156.   case 4  :
  157.     glBegin GL_QUADS
  158.     if cn=0 then
  159.       SurfaceNormal vfn,pm
  160.       @f=@vfn : glNormal3fv f
  161.    end if
  162.     for k=1 to 4
  163.       RenderVertex
  164.     next
  165.     glEnd
  166.   case else :
  167.     'ITR NOT SUPPORTED
  168.  end select
  169.   end macro
  170.   '
  171.  macro ignore()
  172.   ==============
  173.   :
  174.   end macro
  175.   '
  176.  macro CountData()
  177.   =================
  178.   i=1
  179.   le=len d
  180.   cm=0 : cu=0 : cn=0 : cp=0 : cf=0
  181.   do
  182.     StepWord d,i
  183.     if i>=le then exit do 'NO MORE WORDS
  184.    select ascb
  185.     case "v"
  186.       @b=p+sttw+1
  187.       select b
  188.       case "#"  : 'SKIP COMMENT
  189.      case 9,32 : cm++
  190.       case "t"  : cu++
  191.       case "n"  : cn++
  192.       case "p"  : cp++
  193.       end select
  194.     case "f" : cf++ 'COLLECT OR PASS TO OPENGL
  195.    end select
  196.     EndLine d,i
  197.   end do
  198.   end macro
  199.   '
  200.  macro ReadLines()
  201.   =================
  202.   i=1
  203.   smin=0 : smax=0
  204.   do
  205.     StepWord d,i
  206.     if i>=le then exit do 'NO MORE WORDS
  207.    select ascb
  208.     case "v"
  209.       @b=p+sttw+1
  210.       select b
  211.       case "#"  : ignore   'SKIP COMMENT
  212.      case 9,32 : minmax=1 :
  213.                 : vim[1]++ : ReadVertex4D vtm[vim[1]]
  214.                 : minmax=0
  215.       case "t"  : vim[2]++ : ReadVertex3D vtu[vim[2]]
  216.       case "n"  : vim[3]++ : ReadVertex4D vtn[vim[3]]
  217.       case "p"  : vim[4]++ : ReadVertex4D vtp[vim[4]]
  218.       end select
  219.     case "f" : RenderFace : 'COLLECT OR PASS TO OPENGL
  220.    case "m" : ignore 'mtllib
  221.    case "u" : ignore 'usemtl
  222.    case "o" : ignore 'OBJECTS
  223.    case "g" : ignore 'GROUPS
  224.    end select
  225.     EndLine d,i
  226.   end do
  227.   end macro
  228.   '
  229.  macro FreeBuffers()
  230.   ===================
  231.   if @vtm then FreeMemory @vtm
  232.   if @vtu then FreeMemory @vtu
  233.   if @vtn then FreeMemory @vtn
  234.   if @vtp then FreeMemory @vtp
  235.   end macro
  236.   '
  237.  macro NewBuffers()
  238.   ==================
  239.   FreeBuffers
  240.   @vtm = GetMemory cm*sizeof(Vertex4D)
  241.   @vtu = GetMemory cu*sizeof(Vertex3D)
  242.   @vtn = GetMemory cn*sizeof(Vertex4D)
  243.   @vtn = GetMemory cp*sizeof(Vertex4D)
  244.   end macro
  245.   '
  246.  
  247.   function RenderObj()
  248.   ====================
  249.   '
  250.  sys    j,k         'INDEXES AND ITERATORS
  251.  sys    m,n,q       'GENERIC
  252.  sys    sg          'NEG SIGN FLAG FOR RELATIVE VERTEX INDEX
  253.  sys    vj          'VERTEX ARRAY SELECTOR
  254.  sys    vn          'VERTEX INDEX
  255.  float  *f          'FOR GL DATA POINTER
  256.  float  v           'GENERIC
  257.  byte   *b          'SOURCE STRING BYTE READER
  258.  sys    pm[4]       'POINTER TO VERTEX
  259.  sys    pn[4]       'POINTER TO NORMAL
  260.  sys    pp[4]       'POINTER TO PARAMETRIC VECTOR / ITR
  261.  sys    pu[4]       'POINTER TO TEX COORD
  262.  sys    vim[3]      'MAX VERTEX COUNT FOR MAINS,TEXTURES,NORMALS
  263.  sys cf,cm,cu,cn,cp 'COUNTERS
  264.  sys    t1,t2       'TIMERS
  265.  '
  266.  t1=GetTickCount
  267.   '
  268.  Vertex4d vfn       'DEFAULT FACE NORMAL
  269.  Vertex4d *vtm      'FOR GLVERTEX
  270.  Vertex3d *vtu      'FOR GLTEXCOORD
  271.  Vertex4d *vtn      'FOR GLNORMAL
  272.  Vertex4d *vtp      'FOR PARAMETRIC VECTOR
  273.  '
  274.  GetFile ObjFileName,d
  275.   le=len d
  276.   if not le then
  277.     er="Problem accessing file " ObjFileName
  278.     jmp fwd done
  279.   end if
  280.   p=strptr(d)-1
  281.   @b=p 'SOURCE BYTES
  282.  CountData
  283.   string sp="  " ' or tab
  284.  if not cf then
  285.     jmp fwd done
  286.   end if
  287.   NewBuffers
  288.   ReadLines
  289.   FreeBuffers
  290.   done:
  291.   t2=GetTickCount
  292.   status= _
  293.   "Faces: " sp cf sp _
  294.   "Vert:  " sp cm sp _
  295.   "Tex:   " sp cu sp _
  296.   "Norm:  " sp cn sp _
  297.   "Scalar:" sp str(smax-smin,4) sp _
  298.   "mSec:" sp str(t2-t1) sp _
  299.   ""
  300.   if er then status=er
  301.   er=""
  302.   end function
  303.   '
  304.  
  305.   function BuildForm(sys fun) as sys
  306.   '=================================
  307.  '
  308.  'FOR SINGLE OBJECT IN ONE LIST
  309.  '
  310.  static sys list
  311.   if not fun then return 0
  312.   list = CompileList list
  313.   call fun
  314.   glEndList
  315.   return list
  316.   end function
  317.  
  318.   function main()
  319.   ===============
  320.   '
  321.  static sys    shape
  322.   static string inputs="hunter.obj"
  323.  
  324.   cls 0,0.20,0.20
  325.   picksetup
  326.  
  327.   shading
  328.   pushstate
  329.   static MoveableObject mover
  330.   if not mover.id then
  331.     mover.set 0x10000,0,0,0,0
  332.     mover.a.y =180
  333.     mover.aa.y=180
  334.   end if
  335.   sys dt=15
  336.   move dt,-dt*1.5,-dt -1
  337.   mover.act
  338.   'GoldMaterial.act
  339.  'SilverMaterial.act
  340.  'RedShinyMaterial.act
  341.  WhiteShinyMaterial.act
  342.   'go sphere
  343.  float f=smax-smin
  344.   if f then scale 1.25*dt/f
  345.   'scale 1,1,-1.0 'REVERSE Z
  346.  go shape
  347.   popstate
  348.   '
  349.  'LINE INPUT
  350.  '
  351.  flat
  352.   PushState
  353.   color .20,.80,.00,.88
  354.   Scale 1.0
  355.   print "File: "
  356.   color .80,.80,.00,.88
  357.   a=input inputs
  358.   if key(0x74) 'F5
  359.    Objfilename=inputs
  360.     shape=BuildForm(@RenderObj)
  361.     key(0x74)=0 'single shot
  362.  end if
  363.   scale .75
  364.   printl status
  365.   PopState
  366.   printl
  367.   printl
  368.   printl
  369.   '
  370.  '
  371.  shading 'opposite of flat
  372.  '
  373.  '
  374.  'F1 HELP
  375.  '
  376.  if key[0x70]
  377.     flat
  378.     pushstate
  379.     move 20,0
  380.     color .9,.9,.9
  381.     scale  1.5,1.0
  382.     printl "Active Keys:"
  383.     printl
  384.     scale  1/1.5,1.0
  385.     printl "Esc"    tab "Exit"
  386.     printl "Ctrl-P" tab "Take snapshot"
  387.     printl "F1 This help panel"
  388.     printl "F5 Exec function"
  389.     printl
  390.     scale 1.5,1.0
  391.     printl "Mouse:"
  392.     scale 1/1.5,1.0
  393.     printl "Point to Object, then"
  394.     printl "Left button to Rotate"
  395.     printl "Right button to Move"
  396.     popstate
  397.   end if
  398.   picklabel 0
  399.   lastkey=0
  400.   lastchar=0
  401.  
  402.   end function
  403.  
  404.   EndScript
  405.  


.

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #3 on: January 24, 2015, 07:59:45 AM »
Well, the oxy 64bit standalone is not perfect, but this will do for demonstration purposes. The load time for this model on my PC is around 2.3 seconds. I am using classical OpenGl. One of the CPU cores gets fully engaged whenever the model is moved.

I use 4 sample anti-aliasing, which is good for most applications.  The next task is to support materials with mtl files
« Last Edit: January 24, 2015, 12:51:03 PM by Charles Pegge »

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #4 on: January 24, 2015, 12:45:13 PM »
Thanks Patrice,

On my rather ancient and diminutive NVidia GT9, I don't see any flickering or slowness. It runs as smooth as double cream. So I wonder what could be causing these problems.

I'm making a few more corrections. Harley is now working.


.
« Last Edit: January 24, 2015, 12:52:00 PM by Charles Pegge »

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #5 on: January 25, 2015, 02:14:42 AM »
Thanks for your observations, Mike. The world of 3d modellers is new territory for me, apart from some Daz, and the procedural POV-Ray, a few years ago.

I hope I have anticipated most syntax irregularities by using a full parser (inc/ParseUtil.inc), originally sequestered from Lispish :)

I think obj files would be adequate for 3d printing but is there a better modelling format, in your view, we can focus on?

PS: I'm working on a standard set of navigation and model manipulation control by mouse and keyboard. Left and right button functions are easily swapped.

Good luck with your land-line internet!


Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #6 on: January 25, 2015, 02:40:15 AM »
Hi Patrice,

This is the multisampling configuration used in the code. Is there anything in it which might be disruptive to your graphics system?

Code: OxygenBasic
  1.   function SelectMultiSample(sys ns)
  2.   ==================================
  3.   '
  4.  'IDENTIFY MULTISAMPLING FORMAT
  5.  'http://www.opengl.org/wiki/Creating_an_OpenGL_Context#Proper_Context_Creation
  6.  int attribs[]=
  7.   {
  8.     0x2001,1,      'WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
  9.    0x2010,1,      'WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
  10.    0x2011,1,      'WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
  11.    0x2013,0x202B, 'WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
  12.    0x2014,32,     'WGL_COLOR_BITS_ARB, 32,
  13.    0x2022,24,     'WGL_DEPTH_BITS_ARB, 24,
  14.    0x2023,8,      'WGL_STENCIL_BITS_ARB, 8,
  15.    0x2041,1,      'WGL_SAMPLE_BUFFERS_ARB, 1, //Number of buffers (must be 1 at time of writing)
  16.    0x2042,ns,     'WGL_SAMPLES_ARB, 4,        //Number of samples
  17.    0x0000,0       'terminate list
  18.  }
  19.   sys p,a,n
  20.   p=wglGetProcAddress "wglChoosePixelFormatARB"
  21.   if p
  22.     call p(hdc, &attribs, null, 1, &a, &n)
  23.     if n then pixelForm=a : return-1 'supporting multisample / antialias
  24.  end if
  25.   end function
  26.  

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #7 on: January 25, 2015, 07:07:58 PM »
Have you ever encountered Collada? (Digital Asset and FX Exchange Schema)

It seems to cover everything that is conceivable!

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #8 on: January 26, 2015, 08:29:53 AM »
Arc170 with its textures:

.

Frankolinox

  • Guest
Re: Wavefront object viewer
« Reply #9 on: January 26, 2015, 10:38:36 AM »
hi charles, something doesn't work here with your objectviewer example, I cannot run the oxygen example because of this error:

"parseutil.inc", line 188, symbolterm "must use a const expression"
(see picture below)

does the example works for elder machines (32bit) too?

regards, frank

.

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #10 on: January 26, 2015, 11:56:06 AM »
Hi Frank,

I'm still making changes to various source utilities, which is why I'm not posting much code here.

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #11 on: January 26, 2015, 03:42:33 PM »

Hi Patrice, good luck!

I am using your pixel format ARB settings,, except for 24 bit depth buffer instead of 16. I hope it will improve performance on your nVidia. Currently using 4 samples.



Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #12 on: January 28, 2015, 01:47:38 PM »
A little more progress..

.

Charles Pegge

  • Guest
Re: Wavefront object viewer
« Reply #13 on: January 31, 2015, 04:32:16 AM »
Hi Patrice,

Glad you were able to complete your C++ port.

The CVL/MKL functions. do not fit well into C languages. I left them out of OxygenBasic, because Array overlays, (absolute arrays in PB terms) perform the same operations much more efficiently.

For example
Code: OxygenBasic
  1. string s=nuls 1000 'buffer of 1000 null bytes
  2. long v at strptr(s)+64 'long array overlay at offset 64
  3. v[1]=4
  4. v[2]=8
  5.  

I'm waiting for WebGl to mature before diving in - seen a few flops in the past such as vrml and x3d. But, with solid backing, I hope it will stay.



Frankolinox

  • Guest
Re: Wavefront object viewer
« Reply #14 on: January 31, 2015, 11:12:29 AM »
hi charles, I've tried the new "objectviewer.o2bas" example. the example runs but when I am trying to render example (F5) I've got an error with "gxo2.exe" and abort the application.

regards, frank

.