Code archives/File Utilities/Milkshape

This code has been declared by its author to be Public Domain code.

Download source code

Milkshape by Vertex2002
Handle = LoadMS3D("MyModel.ms3d")

Examples:
http://mitglied.lycos.de/thevertex/download.php?c=media\Milkshape.rar

cu olli
; -------------------------------------------------------------------------------------------
; Milkshape-Importer 2.3 by Vertex                                                          :
;                                                                                           :
; Feature:                                                                                  :
;  - Shininess                                                                              :
;  _ Diffuselighting                                                                        :
;  - Alphamaps                                                                              :
;  - Alphatexture                                                                           :
;  - Spheremapping                                                                          :
;                                                                                           :
; To do:                                                                                    :
;  - Including Animation                                                                    :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function LoadMS3D(File$,Parent = 0)
    Local Stream,Vertices,Triangles,Groups,Materials
    Local Animation,Joints,Mesh,crtMaterials,crtGroups

    Stream = ReadFile(File$)
    If Stream = False Then
        Return False
    EndIf

    If ms3dCheckHeader(Stream) = False Then
        CloseFile Stream
        Return False
    EndIf

    Vertices  = ms3dLoadVertices(Stream)
    Triangles = ms3dLoadTriangles(Stream)
    Groups    = ms3dLoadGroups(Stream)
    Materials = ms3dLoadMaterials(Stream)
    ;Animation = ms3dLoad_Animation(Stream)
    ;Joints    = ms3dLoad_Joints(Stream)

    CloseFile Stream

    If Parent Then
        Mesh = CreateMesh(Parent)
    Else
        Mesh = CreateMesh()
    EndIf 

    crtMaterials = ms3dCreateMaterials(File$,Materials)
    crtGroups    = ms3dCreateGroups(Mesh,Groups,crtMaterials)
                   ms3dCreateVertices(Vertices,Triangles,crtGroups)
                   ms3dCreateTriangles(Triangles,crtGroups)
    Return Mesh
End Function
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dCheckHeader(Stream)                                    ;         Header        :
    Local I,ID$,Version                                             ;-----------------------:
                                                                    ;                       :
    For I = 1 To 10                                                 ;                       :
        ID$ = ID$ + Chr$(ReadByte(Stream))                          ; ID                    :
    Next                                                            ;                       :
    If ID$ <> "MS3D000000" Then                                     ;                       :
        Return False                                                ;                       :
    EndIf                                                           ;                       :
                                                                    ;                       :
    Version = ReadInt(Stream)                                       ; Version               :
    If Version <> 4 Then                                            ;                       :
        Return False                                                ;                       :
    EndIf                                                           ;                       :
                                                                    ;                       :
    Return True                                                     ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadVertices(Stream)                                   ;        Vertices       :
    Local VertexCount,Vertices,I                                    ;-----------------------;
                                                                    ;                       :
    VertexCount = ReadShort(Stream)                                 ;                       :
    Vertices    = CreateBank(VertexCount * 13 + 2)                  ;                       :
    PokeShort     Vertices,0,VertexCount                            ;                       :
                                                                    ;                       :
    For I = 1 To VertexCount                                        ;                       :
        SeekFile  Stream,FilePos(Stream) + 1                        ; Flags                 :
        ReadBytes Vertices,Stream,(I - 1) * 13 + 02,12              ; Position              :
        PokeByte  Vertices,(I - 1) * 13 + 14,ReadByte(Stream)       ; BoneID                :
        SeekFile  Stream,FilePos(Stream) + 1                        ; ReferenceCount        :
    Next                                                            ;                       :
                                                                    ;                       :
       Return Vertices                                              ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadTriangles(Stream)                                  ;       Triangles       ;
    Local TriangleCount,Triangles,I                                 ;-----------------------:
                                                                    ;                       :
    TriangleCount = ReadShort(Stream)                               ;                       :
    Triangles     = CreateBank(TriangleCount * 67 + 2)              ;                       :
    PokeShort       Triangles,0,TriangleCount                       ;                       :
                                                                    ;                       :
       For I = 1 To TriangleCount                                   ;                       :
        SeekFile  Stream,FilePos(Stream) + 2                        ; Flags                 :
        ReadBytes Triangles,Stream,(I - 1) * 67 + 02,6              ; Vertexindices         :
        ReadBytes Triangles,Stream,(I - 1) * 67 + 08,36             ; Vertexnormals         :
        ReadBytes Triangles,Stream,(I - 1) * 67 + 44,24             ; Vertextexcoords       :
        SeekFile  Stream,FilePos(Stream) + 1                        ; Smoothinggroup        :
        PokeByte  Triangles,(I - 1) * 67 + 68,ReadByte(Stream)      ; Groupindex            :
    Next                                                            ;                       :
                                                                    ;                       :
    Return Triangles                                                ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------
Function ms3dLoadGroups(Stream)                                     ;         Groups        :
    Local GroupCount,Groups,I,Dummy                                 ;-----------------------:
                                                                    ;                       :
    GroupCount = ReadShort(Stream)                                  ;                       :
    Groups     = CreateBank(GroupCount + 2)                         ;                       :
    PokeShort    Groups,0,GroupCount                                ;                       :
                                                                    ;                       :
    For I = 1 To GroupCount                                         ;                       :
        SeekFile Stream,FilePos(Stream) + 1                         ; Flags                 :
        SeekFile Stream,FilePos(Stream) + 32                        ; Name                  :
        Dummy  = ReadShort(Stream)                                  ; numTriangle           :
        SeekFile Stream,FilePos(Stream) + (Dummy * 2)               ; Triangle              :
        PokeByte Groups,I - 1 + 2,ReadByte(Stream)                  ; Materialindex         :
    Next                                                            ;                       :
                                                                    ;                       :
    Return Groups                                                   ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadMaterials(Stream)                                  ;       Materials       :
    Local MaterialCount,Material,I                                  ;-----------------------:
                                                                    ;                       :
    MaterialCount = ReadShort(Stream)                               ;                       :
    Material      = CreateBank(MaterialCount * 277 + 2)             ;                       :
    PokeShort       Material,0,MaterialCount                        ;                       :
                                                                    ;                       :
    For I = 1 To MaterialCount                                      ;                       :
        SeekFile  Stream,FilePos(Stream) + 32                       ; Name                  :
        SeekFile  Stream,FilePos(Stream) + 16                       ; Ambient RGBA          :
        ReadBytes Material,Stream,(I - 1) * 277 + 2,12              ; Difusse RGB           :
        SeekFile  Stream,FilePos(Stream) + 4                        ; Difusse A             :
        SeekFile  Stream,FilePos(Stream) + 16                       ; Specular RGBA         :
        SeekFile  Stream,FilePos(Stream) + 16                       ; Emissive RGBA         :
        PokeFloat Material,(I - 1) * 277 + 14,ReadFloat#(Stream)    ; Shininess             :
        PokeFloat Material,(I - 1) * 277 + 18,ReadFloat#(Stream)    ; Transparency          :
        PokeByte  Material,(I - 1) * 277 + 22,ReadByte(Stream)      ; Mode                  :
        ReadBytes Material,Stream,(I - 1) * 277 + 023,128           ; Filename              :
        ReadBytes Material,Stream,(I - 1) * 277 + 151,128           ; Alphamap              :
    Next                                                            ;                       :
                                                                    ;                       :
    Return Material                                                 ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadAnimation(Stream)                                  ;       Animation       :
    Local Animation                                                 ;-----------------------:
                                                                    ;                       :
    Animation = CreateBank(12)                                      ;                       :
    PokeFloat Animation,0,ReadFloat#(Stream)                        ; Aniamations FPS       :
    PokeFloat Animation,0,ReadFloat#(Stream)                        ; Curent time           :
    PokeInt   Animation,0,ReadInt(Stream)                           ; Total frames          :
                                                                    ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------
    
; -------------------------------------------------------------------------------------------
Function ms3dLoadJoints(Stream)                                     ;         Joints        :
    Local JointCount,Joints,I,KeyRotCount,KeyPosCount               ;-----------------------:
                                                                    ;                       :
    JointCount = ReadShort(Stream)                                  ;                       :
    Joints     = CreateBank(JointCount * 100 + 2)                   ;                       :
    PokeShort    Joints,0,JointCount                                ;                       :
                                                                    ;                       :
    For I = 1 To JointCount                                         ;                       :
        SeekFile      Stream,FilePos(Stream) + 1                    ; Flags                 :
        ReadBytes     Joints,Stream,(I - 1) * 100 + 02,32           ; Name                  :
        ReadBytes     Joints,Stream,(I - 1) * 100 + 34,32           ; Parentname            :
        ReadBytes     Joints,Stream,(I - 1) * 100 + 66,12           ; Rotation              :
        ReadBytes     Joints,Stream,(I - 1) * 100 + 78,12           ; Position              :
        KeyRotCount = ReadShort(Stream)                             ; Keycount of rotation  :
        KeyPosCount = ReadShort(Stream)                             ; Keycount of position  :
        KeyRot      = ms3dLoadKeyRot(Stream,KeyRotCount)            ; Keyframes of rotation :
        KeyPos      = ms3dLoadKeyPos(Stream,KeyPosCount)            ; Keyframes of position :
        PokeShort     Joints,(I - 1) * 100 + 90,KeyRotCount         ;                       :
        PokeShort     Joints,(I - 1) * 100 + 92,KeyPosCount         ;                       :
        PokeShort     Joints,(I - 1) * 100 + 94,KeyRot              ;                       :
        PokeShort     Joints,(I - 1) * 100 + 96,KeyPos              ;                       :
    Next                                                            ;                       :
                                                                    ;                       :
    Return Joints                                                   ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadKeyRot(Stream,Count)                               ;         KeyRot        :
    Local KeyRot,I                                                  ;-----------------------:
                                                                    ;                       :
    KeyRot = CreateBank(Count * 16)                                 ;                       :
                                                                    ;                       :
    For I = 1 To Count                                              ;                       :
       PokeFloat KeyRot,(I - 1) * 16 + 00,ReadFloat#(Stream)        ; Time                  :
       ReadBytes KeyRot,Stream,(I - 1) * 16 + 04,12                 ; Rotation              :
    Next                                                            ;                       :
                                                                    ;                       :
    Return KeyRot                                                   ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dLoadKeyPos(Stream,Count)                               ;         KeyPos        :
    Local KeyPos,I                                                  ;-----------------------:
                                                                    ;                       :
    KeyPos = CreateBank(Count * 16)                                 ;                       :
                                                                    ;                       :
    For I = 1 To Count                                              ;                       :
       PokeFloat KeyPos,(I - 1) * 16 + 00,ReadFloat#(Stream)        ; Time                  :
       ReadBytes KeyPos,Stream,(I - 1) * 16 + 04,12                 ; Position              :
    Next                                                            ;                       :
                                                                    ;                       :
    Return KeyRot                                                   ;                       :
End Function                                                        ;                       :
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dCreateMaterials(File$,BnkMaterials)
    Local MaterialCount,Material,I,Mode,J
    Local Texturefile$,Alphafile$,Texture,Alphamap
    Local R,G,B,Brush

    MaterialCount = PeekShort(BnkMaterials,0)
    Material      = CreateBank(MaterialCount * 4)

    For I = 1 To MaterialCount
        If PeekByte(BnkMaterials,(I - 1) * 277 + 22) = 128 Then
            Mode = 64
        Else 
            Mode = 1
        EndIf

        For J = (I - 1) * 277 + 023 To (I - 1) * 277 + 151
            If PeekByte(BnkMaterials,J) <> 0 Then
                Texturefile$ = Texturefile$ + Chr$(PeekByte(BnkMaterials,J))
            Else
                Exit
            EndIf
        Next
        Texturefile$ = ms3dGetPath$(File$,Texturefile$)

        For J = (I - 1) * 277 + 151 To (I - 1) * 277 + 289
            If PeekByte(BnkMaterials,J) <> 0 Then
                Alphafile$ = Alphafile$ + Chr$(PeekByte(BnkMaterials,J))
            Else
                Exit
            EndIf
        Next
        Alphafile$ = ms3dGetPath$(File$,Alphafile$)

        Texture = LoadTexture(Texturefile$,Mode)
        R = PeekFloat#(BnkMaterials,(I - 1) * 277 + 02) * 255.0
        G = PeekFloat#(BnkMaterials,(I - 1) * 277 + 06) * 255.0
        B = PeekFloat#(BnkMaterials,(I - 1) * 277 + 10) * 255.0

        If Texture = False Then
            Brush = CreateBrush(R,G,B)
        Else
            FreeTexture Texture
            Alphamap = LoadTexture(Alphafile$)
            If Alphamap Then
                Texture = LoadTexture(Texturefile$,Mode + 2)
                ms3dSetAlphamap(Texture,Alphamap)
                FreeTexture Alphamap
            Else
                Texture = LoadTexture(Texturefile$,Mode)
            EndIf
            Brush = CreateBrush()
            BrushTexture Brush,Texture
            BrushColor   Brush,R,G,B
            FreeTexture  Texture
        EndIf
        BrushShininess Brush,PeekFloat#(BnkMaterials,(I - 1) * 277 + 14)
        BrushAlpha     Brush,PeekFloat#(BnkMaterials,(I - 1) * 277 + 18)

        PokeInt Material,(I - 1) * 4,Brush
    Next

    Return Material
End Function 
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dCreateGroups(Mesh,BnkGroups,BnkMaterial)
    Local GroupCount,Group,I,Material,Brush,Surface

    GroupCount = PeekShort(BnkGroups,0)
    Group      = CreateBank(GroupCount * 4)

    For I = 1 To GroupCount
        Material = PeekByte(BnkGroups,I + 1)
        If Material <> 255 Then
            Brush = PeekInt(BnkMaterial,Material * 4)
            Surface = CreateSurface(Mesh,Brush)
        Else
            Surface = CreateSurface(Mesh)
        EndIf

        PokeInt Group,(I - 1) * 4,Surface
    Next

    Return Group
End Function 
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dCreateVertices(BnkVertices,BnkTriangles,BnkGroup)
    Local VertexCount,Group,TriangleCount,I,GI,V0,V1,V2,X#,Y#,Z#
    Local Surface,NX0#,NY0#,NZ0#,NX1#,NY1#,NZ1#,NX2#,NY2#,NZ2#
    Local TU0#,TV0#,TU1#,TV1#,TU2#,TV2#

    VertexCount   = PeekShort(BnkVertices,0)
    Group        = CreateBank(VertexCount)
    TriangleCount = PeekShort(BnkTriangles,0)

    For I = 1 To TriangleCount
        GI = PeekByte(BnkTriangles,(I - 1) * 67 + 68)
        V0 = PeekShort(BnkTriangles,(I - 1) * 67 + 02)
        V1 = PeekShort(BnkTriangles,(I - 1) * 67 + 04)
        V2 = PeekShort(BnkTriangles,(I - 1) * 67 + 06)
        PokeByte Group,V0,GI
        PokeByte Group,V1,GI
        PokeByte Group,V2,GI
    Next

    For I = 1 To VertexCount
        X# = PeekFloat#(BnkVertices,(I - 1) * 13 + 02)
        Y# = PeekFloat#(BnkVertices,(I - 1) * 13 + 06)
        Z# = PeekFloat#(BnkVertices,(I - 1) * 13 + 10)
        GI = PeekByte(Group,I - 1)
        Surface = PeekInt(BnkGroup,GI * 4)
        AddVertex(Surface,X#,Y#,Z#)
    Next
    FreeBank Group

    For I = 1 To TriangleCount
        GI = PeekByte(BnkTriangles,(I - 1) * 67 + 68)
        V0 = PeekShort(BnkTriangles,(I - 1) * 67 + 02)
        V1 = PeekShort(BnkTriangles,(I - 1) * 67 + 04)
        V2 = PeekShort(BnkTriangles,(I - 1) * 67 + 06)
        Surface = PeekInt(BnkGroup,GI * 4)

        NX0# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 08)
        NY0# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 12)
        NZ0# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 16)
        NX1# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 20)
        NY1# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 24)
        NZ1# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 28)
        NX2# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 32)
        NY2# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 36)
        NZ2# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 40)
        TU0# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 44)
        TU1# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 48)
        TU2# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 52)
        TV0# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 56)
        TV1# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 60)
        TV2# = PeekFloat#(BnkTriangles,(I - 1) * 67 + 64)
        
        VertexNormal Surface,V0,NX0#,NY0#,NZ0#
        VertexNormal Surface,V1,NX1#,NY1#,NZ1#
        VertexNormal Surface,V2,NX2#,NY2#,NZ2#
        VertexTexCoords Surface,V0,TU0#,TV0#
        VertexTexCoords Surface,V1,TU1#,TV1#
        VertexTexCoords Surface,V2,TU2#,TV2#
    Next
End Function 
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dCreateTriangles(BnkTriangles,BnkGroup)
    Local TriangleCount,I,GI,V0,V1,V2,Surface

    TriangleCount = PeekShort(BnkTriangles,0)
    For I = 1 To TriangleCount
        GI = PeekByte(BnkTriangles,(I - 1) * 67 + 68)
        V0 = PeekShort(BnkTriangles,(I - 1) * 67 + 02)
        V1 = PeekShort(BnkTriangles,(I - 1) * 67 + 04)
        V2 = PeekShort(BnkTriangles,(I - 1) * 67 + 06)
        Surface = PeekInt(BnkGroup,GI * 4)
        AddTriangle Surface,V0,V1,V2
    Next
End Function 
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dGetPath$(File1$,File2$)
    Local I,LastBackshlash

    If Left$(File2$,1) = "." Or Left$(File2$,1) = "\" Then
        For I = 1 To Len(File1$)
            If Mid$(File1$,I,1) = "\" Then LastBackshlash = I
        Next
        Return Left$(File1$,LastBackshlash) + File2$
    Else
        Return File2$
    EndIf
End Function
; -------------------------------------------------------------------------------------------

; -------------------------------------------------------------------------------------------
Function ms3dSetAlphamap(Texture,Alphamap)
    Local OldBuffer,TexBuffer,AlphaBuffer
    Local TexWidth,TexHeight,AlphaWidth
    Local AlphaHeight,M1#,M2#,X,Y,RGB1,R,G,B
    Local RGB2,A,ARGB

    OldBuffer   = GraphicsBuffer()
    TexBuffer   = TextureBuffer(Texture)
    AlphaBuffer = TextureBuffer(Alphamap)
    TexWidth    = TextureWidth(Texture)
    TexHeight   = TextureHeight(Texture)
    AlphaWidth  = TextureWidth(Alphamap)
    AlphaHeight = TextureHeight(Alphamap)
    M1#         = Float#(TexWidth) / Float#(AlphaWidth)
    M2#         = Float#(TexHeight) / Float#(AlphaHeight)

    SetBuffer TexBuffer : LockBuffer
    LockBuffer AlphaBuffer
    For X = 0 To TexWidth - 1
        For Y = 0 To TexHeight - 1
            RGB1 = ReadPixelFast(X,Y,TexBuffer)
            R    = (RGB1 And $FF0000) / $10000
            G    = (RGB1 And $FF00) / $100
            B    = (RGB1 And $FF)

            RGB2 = ReadPixelFast(M1# * X,M2# * Y,AlphaBuffer)
            A    = (RGB2 And $FF0000) / $10000
            ARGB = A * $1000000 + R * $10000 + G * $100 + B
            WritePixelFast(X,Y,ARGB,TexBuffer)
        Next
    Next
    UnlockBuffer AlphaBuffer
    UnlockBuffer : SetBuffer OldBuffer
End Function
; -------------------------------------------------------------------------------------------

Comments

None.

Code Archives Forum