3ds loader for dos needed

DOS specific questions.
Post Reply
fatman2021
Posts: 215
Joined: Dec 14, 2013 0:43

3ds loader for dos needed

Post by fatman2021 »

Does anyone know know how to load .3ds using the dos version of freebasic?


Note: I have my own graphics library that I plan on using....
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: 3ds loader for dos needed

Post by D.J.Peters »

basic 3ds loader stuff

Code: Select all

#define DEBUG

#ifdef DEBUG
# define dprint(_msg_) open err for output as #99 : print #99,_msg_ : close #99
#else
# define dprint(_msg_) :
#endif

type V3D ' vertex
  as single x,y,z
end type

type F3D ' face
  as ushort a,b,c,f
end type

type T2D ' texture coords
  as single u,v
end type

type fRGB
  as single r,g,b
end type

type MAP
  as string Path
  as single Amount
  as single UScale   ' 1/U
  as single VScale   ' 1/V
  as single UOffset
  as single VOffset
  as single Rotation ' angle
end type

type MATERIAL
  as string  Caption

  as MAP ptr TextureMap
  as MAP ptr TextureMap2
  as MAP ptr SpecularMap
  as MAP ptr OpacityMap
  as MAP ptr BumpMap
  as MAP ptr ReflectionMap

  as fRGB    Ambient
  as fRGB    Diffuse
  as fRGB    Specular
  as single  Emissive
 
  as single  Shininess
  as single  ShininessStrength
 
  as single  Transparency
  as single  TransparencyFallOff
 
  as single  ReflectionBlure
  as single  AmountBumpMap
  as integer Shading ' 1=flat 2=gour. 3 phong, 4 metal

  as long TwoSided ' is 0 or 1 after loading
  as long Decal    ' is 0 or 1 after loading
  as long Additive ' is 0 or 1 after loading
  as long WireOn   ' is 0 or 1 after loading
  as long FaceMap  ' is 0 or 1 after loading
 
end type

type PART3DS
  as string PartName
  as V3D ptr pV
  as V3D ptr pN
  as F3D ptr pF
  as T2D ptr pT
  as long nV,nF,nT,nM
  as single m4x3(3,2)
end type

type OBJECT3DS
  declare constructor(FileName as string="")
  declare destructor
  declare sub Load(FileName as string)
  declare sub Release
  as MATERIAL ptr ptr Mats
  as PART3DS  ptr ptr Parts
  as long          nParts,nMats
end type

constructor OBJECT3DS(FileName as string)
  if len(FileName) then Load FileName
end constructor

destructor OBJECT3DS
  Release
end destructor

sub OBJECT3DS.Release()
  ' a list of parts ?
  if Parts then
    ' any part ?
    if nParts<>0 then
      ' loop over all parts
      for pc as long = 0 to nParts-1
        if Parts[pc] then
          ' vertices
          if Parts[pc]->pV then delete[] Parts[pc]->pV
          ' normals
          if Parts[pc]->pN then delete[] Parts[pc]->pN
          ' texture coords
          if Parts[pc]->pT then delete[] Parts[pc]->pT
          ' face indicies
          if Parts[pc]->pF then delete[] Parts[pc]->pF
        end if
      next
    end if
    deallocate Parts:Parts=0
    nParts=0
  end if
  ' a list of materials ?
  if Mats then
    ' any material
    if nMats>0 then
      ' loop over all materials
      for mc as long = 0 to nMats-1
        if Mats[mc] then
          if Mats[mc]->TextureMap    then delete Mats[mc]->TextureMap
          if Mats[mc]->TextureMap2   then delete Mats[mc]->TextureMap2
          if Mats[mc]->SpecularMap   then delete Mats[mc]->SpecularMap
          if Mats[mc]->ReflectionMap then delete Mats[mc]->ReflectionMap
          if Mats[mc]->OpacityMap    then delete Mats[mc]->OpacityMap
          if Mats[mc]->BumpMap       then delete Mats[mc]->BumpMap
          delete Mats[mc]
        end if
      next
    end if
    deallocate Mats:Mats=0
    nMats=0
  end if
end sub


function ReadColor(hFile as long, _
                   byref sR as single, _
                   byref sG as single, _
                   byref sB as single) as ushort
  dim as ushort id
  dim as long size
  get #hFile,,id
  get #hFile,,size
  select case id
    case &H0010,&H0013
      dim as single r,g,b
      get #hFile,,r : get #hFile,,g : get #hFile,,b
      sR=r:sG=g:sB=b : return 18
    case &H0011,&H0012
      dim as ubyte r,g,b
      get #hFile,,r : get #hFile,,g : get #hFile,,b
      sR = (1.0/255.0)*r : sG = (1.0/255.0)*g : sB = (1.0/255.0)*b
      return 9
    case else
      dprint("error: unknown color chunk 0x" & hex(id,4))
      beep:sleep:end
    end select
  return 6
end function

function ReadPercent(hFile as long,byref perc as ushort) as ushort
  dim as ushort  id
  dim as long size
  dim as single  pf
  get #hFile,,id
  get #hFile,,size
  select case id
    case &H0030
      get #hFile,,perc:return 8
    case &H0031
      get #hFile,,pf
      '? "0x0031 " & pf & " % " & " " & size
      perc = pf*100.0:return 10
    case else
      dprint("error: unknown percent chunk 0x" & hex(id,4))
      beep:sleep:end
  end select
  return 6
end function

sub OBJECT3DS.Load(FileName as string)
  const BIG_NUMBER as single = 100000000.0
 
  dim as long hFile = FreeFile()
  if open(FileName,for binary,access read,as #hFile) then
    dprint("error: can't open " & FileName)
    return
  end if

  dim as string   txt
  dim as ushort   ID,nItems,u16
  dim as short    s16
  dim as long     Size,s32
  dim as ulong    u32
  dim as ubyte    char
  dim as single   r,g,b,f32
  dim as MAP ptr  CurrentMap
 
  while not eof(hFile)
    get #hFile,,ID
    get #hFile,,Size
    Size-=6
    select case ID
    case &H4D4D
      dprint("main:")

    case &H0002
      get #hFile,,u32:size-=4
      dprint("3DS ver. " & u32)

    case &H0100 to &H3D3C ' editor settings
      seek hFile,seek(hFile)+Size : Size=0
      dprint("editor settings")

    case &H3D3D
      dprint("editor:")

    case &H3D3E
      get #hFile,,u32:size-=4
      dprint( "mesh ver. " & u32)

    case &HAFFF ' material chunk
      dprint("material:")

    case &HA000 ' material name
      txt=""
      do
        get #hFile,,char : size-=1
        if char then txt &= chr(char)
      loop until char=0
      dprint("m: mats[" & nMats & "] = " & txt)
      nMats+=1
      Mats = reallocate( Mats, sizeof(MATERIAL) * nMats )
      Mats[nMats-1] = new MATERIAL
      Mats[nMats-1]->Caption = txt

    case &HA010 ' ambient
      while size : size -= ReadColor(hFile,r,g,b) : wend
      Mats[nMats-1]->Ambient.r=r
      Mats[nMats-1]->Ambient.g=g
      Mats[nMats-1]->Ambient.b=b
      dprint("amb: " & Mats[nMats-1]->Ambient.r & ","  & Mats[nMats-1]->Ambient.g & "," & Mats[nMats-1]->Ambient.b)

    case &HA020 ' diffuse
      while size: size -= ReadColor(hFile,r,g,b) : wend
      Mats[nMats-1]->Diffuse.r=r
      Mats[nMats-1]->Diffuse.g=g
      Mats[nMats-1]->Diffuse.b=b
      dprint("dif: " & Mats[nMats-1]->Diffuse.r & ","  & Mats[nMats-1]->Diffuse.g & "," & Mats[nMats-1]->Diffuse.b)

    case &HA030 ' specular
      while size: size -= ReadColor(hFile,r,g,b) : wend
      Mats[nMats-1]->Specular.r=r
      Mats[nMats-1]->Specular.g=g
      Mats[nMats-1]->Specular.b=b
      dprint("spc: " & Mats[nMats-1]->Specular.r & ","  & Mats[nMats-1]->Specular.g & "," & Mats[nMats-1]->Specular.b)

    case &HA040 ' shininess (percent)
      size -= ReadPercent(hFile,u16)
      Mats[nMats-1]->Shininess = u16/100.0
      dprint("shy: " & Mats[nMats-1]->Shininess)

    case &HA041 ' shininess strength (percent)
      size -= ReadPercent(hFile,u16)
      '? "m: shi strength" & shinystr
      Mats[nMats-1]->ShininessStrength = u16/100.0
      dprint("shy strength: " & Mats[nMats-1]->ShininessStrength)

    case &HA050 ' transparency (percent)
      size -= ReadPercent(hFile,u16)
      '? "m: tra " & tran & "% "  & size
      Mats[nMats-1]->Transparency = u16/100.0
      dprint("tra: " & Mats[nMats-1]->Transparency)

    case &HA052  ' transparency falloff percent
      size -= ReadPercent(hFile,u16)
      Mats[nMats-1]->TransparencyFallOff = u16/100.0
      dprint("tra of: " & Mats[nMats-1]->TransparencyFallOff)

    case &HA053  ' reflection blur percent
      size -= ReadPercent(hFile,u16)
      '? "ref. blure " & refb & "% " & size
      Mats[nMats-1]->ReflectionBlure = u16/100.0
   
    case &HA100  ' render flags 1=flat,gour.,phong, metal
      get #hFile,,u16:size-=2
      dprint("Shading flag: " & u16)
      Mats[nMats-1]->Shading = u16
   
    case &HA084 ' self illumisation
      size -= ReadPercent(hFile,u16)
      Mats[nMats-1]->Emissive = u16/100.0
      dprint("Ems: " & Mats[nMats-1]->Emissive)

    case &HA081 ' 2 sided
      Mats[nMats-1]->TwoSided=1
      dprint("m: 2 Sided")

    case &HA082 ' Decal
      Mats[nMats-1]->Decal=1
      dprint("m: Decal")

    case &HA083 ' Transparency ADD
      dprint("m: Additive")
      Mats[nMats-1]->Additive=1

    case &HA085 ' Wire on
      Mats[nMats-1]->WireOn=1
      dprint("m: WireOn")

    case &HA087 ' Wire thickness
      get #hFile,,f32:size-=4

    case &HA088 ' Face map
       Mats[nMats-1]->FaceMap=1
       dprint("m: FaceMap")

    case &HA08E
      ' Wire in units  

    case &HA08A ' In tranc
      seek hFile,seek(hFile)+Size : Size=0

    case &HA08C ' Soften
      seek hFile,seek(hFile)+Size : Size=0

    case &HA200 '* texture map 1
      dprint("Texture map " & size)
      Mats[nMats-1]->TextureMap = new MAP
      CurrentMap = Mats[nMats-1]->TextureMap
    case &HA204 '* specular map
      dprint("Specular map " & size)
      Mats[nMats-1]->SpecularMap = new MAP
      CurrentMap = Mats[nMats-1]->SpecularMap
    case &HA210 ' * opacity map
      dprint("Opacity map " & size)
      Mats[nMats-1]->OpacityMap = new MAP
      CurrentMap = Mats[nMats-1]->OpacityMap
    case &HA220 ' * reflection map
      dprint("Refelction map " & size)
      Mats[nMats-1]->ReflectionMap = new map
      CurrentMap = Mats[nMats-1]->ReflectionMap
    case &HA230 ' * bump map
      dprint("Bump map " & size)
      Mats[nMats-1]->BumpMap = new MAP
      CurrentMap = Mats[nMats-1]->BumpMap
    case &HA33A ' texture map 2
      dprint("Texture map 2 " & size)
      Mats[nMats-1]->TextureMap2 = new MAP
      CurrentMap = Mats[nMats-1]->TextureMap2
   
    case &HA252 ' bump map perentage
      get #hFile,,u16:size-=2
      Mats[nMats-1]->AmountBumpMap = u16/100.0
      dprint( "bump pres. " & Mats[nMats-1]->AmountBumpMap)

    case &H0030
      get #hFile,,u16:size-=2
      CurrentMap->Amount = u16/100.0
      dprint("map amount " & CurrentMap->Amount)
      CurrentMap->UScale = 1.0
      CurrentMap->VScale = 1.0

    case &HA300
      txt=""
      do
        get #hFile,,char : size-=1
        if char then txt &=chr(char)
      loop until char=0
      CurrentMap->Path = txt
      dprint("map path " & CurrentMap->Path & "," & nMats-1)

    case &HA351
      get #hFile,,u16 : size-=2
      '? "map options = " & options & " " & size  

    case &HA353 ' Blur percent
      get #hFile,,f32 : size-=4
      '? "blur = " & bper & " " & size  :

    case &HA354
      get #hFile,,f32 : size-=4
      CurrentMap->UScale = f32
      dprint("1/U = " & CurrentMap->UScale)

    case &HA356
      get #hFile,,f32 : size-=4
      CurrentMap->VScale = f32
      dprint("1/V = " & CurrentMap->VScale)

    case &HA358
      get #hFile,,f32 : size-=4
      CurrentMap->UOffset = f32
      dprint("U offset = " & CurrentMap->UOffset)
    case &HA35A
      get #hFile,,f32 : size-=4
      CurrentMap->VOffset = f32
      dprint("V offset = " & CurrentMap->VOffset)

    case &HA35C ' Rotation angle
      get #hFile,,f32 : size-=4
      CurrentMap->Rotation = f32
      dprint("Z rotation = " & CurrentMap->Rotation)

    case &H4000 ' new object
      txt=""
      do
        get #hFile,,char : size-=1
        if char then txt &=chr(char)
      loop until char=0
      nParts+=1
      dprint("p: [" & nParts & "] " & txt)
      Parts = reallocate(Parts,sizeof(PART3DS ptr)*nParts)
      Parts[nParts-1] = new PART3DS
      Parts[nParts-1]->PartName = txt

    case &H4100 ' new object of kind trimesh
      dprint("new triangle mesh")

    case &H4110 ' vertex list
      get #hfile,,nItems : size-=2
      dprint("v: " & nItems)
      Parts[nParts-1]->nV = nItems : size-=nItems*12
      Parts[nParts-1]->pV = new V3D[nItems]:get #hFile,,*Parts[nParts-1]->pV,nItems

    case &H4111 ' vertex options in editor (selected, ...)
      seek hFile,seek(hFile)+Size : Size=0

    case &H4120 ' face list
      get #hfile,,nItems : Size-=2
      dprint("f: " & nItems)
      Parts[nParts-1]->nF = nItems : Size-=nItems*8
      Parts[nParts-1]->pF = new F3D[nItems]:get #hFile,,*Parts[nParts-1]->pF,nItems
     
    case &H4130 ' triangle material
      dim as ushort fIndx,mIndx=&HFFFF
      txt=""
      do
        get #hFile,,char : size-=1
        if char then txt &=chr(char)
      loop until char=0
      ' search the material index from name
      for i as long=0 to nMats-1
        if Mats[i]->Caption=txt then
          mIndx=i:exit for
        end if
      next

      if mIndx=&HFFFF then
        dprint("error: no matching material !")
        beep:sleep:end
      end if
      ' set material index to triangle index
      get #hFile,,nItems : Size-=2
      for i as long = 0 to nItems-1
        get #hfile,,fIndx : size-=2
        Parts[nParts-1]->pF[fIndx].f=mIndx
      next
     
    case &H4140 ' triangle mapping coords
      get #hfile,,nItems: size-=2
      dprint("t: " & nItems)
      Parts[nParts-1]->nT = nItems : Size -= nItems*8
      Parts[nParts-1]->pT = new T2D[nItems]:get #hFile,,*Parts[nParts-1]->pT,nItems
   
    case &H4150 ' triangle smoothing group
       seek hFile,seek(hFile)+Size : Size=0
     
    case &H4160 ' object local axis and center position
      get #hfile,,Parts[nParts-1]->m4x3() :  Size-=12*4
      #ifdef DEBUG
      dprint("axis and center:")
      for i as long=0 to 3
        dprint(str(Parts[nParts-1]->m4x3(i,0)) & "," & str(Parts[nParts-1]->m4x3(i,1))  & "," & str(Parts[nParts-1]->m4x3(i,2)))
      next
      #endif
     
    case &H4165 to &H4FFFF ' editor color, lights etc.
      seek hFile,seek(hFile)+Size : Size=0
     
    case &H7001,&H7011,&H7012,&H7020  ' editor window description
      seek hFile,seek(hFile)+Size : Size=0
   
    case &HB000 ' keyframes
      seek hFile,seek(hFile)+Size  : Size=0

    case else
      ' jump over unsorprted chunk
      seek hFile,seek(hFile)+Size : Size=0
      dprint("chunck ignored 0x" & hex(id,4))
      beep
    end select
  wend
  close #hFile
end sub
fatman2021
Posts: 215
Joined: Dec 14, 2013 0:43

Re: 3ds loader for dos needed

Post by fatman2021 »

thanks a lot....
Post Reply