Чтение двоичного файла .fbx в golang - PullRequest
0 голосов
/ 24 августа 2018

В отличие от других языков, я действительно не мог понять, как прочитать двоичный файл в массив байтов или просто превратить его в ASCII-строку, что ставит меня в довольно большую проблему.

Код, который я использовал:

func TestFBX(fileName string) {
    file, err := os.Open(fileName)
    if (err != nil) {
        log.Fatal(err)
    }
    defer file.Close()

    var content []byte
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        text := []byte(scanner.Text())
        buf := bytes.NewReader(text)
        err := binary.Read(buf, binary.LittleEndian, &content)

        if (err != nil) {
            fmt.Println(err)
        }
    }

    fmt.Printf("%v", content)
    fmt.Println("")

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
}

В конце концов он печатает [], пустой фрагмент.Теперь, когда я попытался поместить float64 или int32 вместо [] байта, он распечатал разные числа, но я все еще честно не понимаю, как читать весь файл , а не только то, какое число есть в начале.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Если вы все еще заинтересованы в golang FBX Reader, вот моя реализация https://github.com/o5h/fbx. Не проверено, но должно работать.

Внутренне FBX имеют следующую структуру:

type Header [27]byte
type FBX struct {
  Header *Header
  Top    *Node
  Nodes  []*Node
}
type Node struct {
  EndOffset       uint32
  NumProperties   uint32
  PropertyListLen uint32
  NameLen         uint8
  Name            string
  Properties      []*Property
  NestedNodes     []*Node
 }
 type Property struct {
  TypeCode byte
  Data     interface{}
 }

Вот пример использования:

f, _ := os.Open("cube.fbx")
defer f.Close()
fbxData, _ := fbx.ReadFrom(f)
ibo := fbxData.Filter(fbx.FilterName("PolygonVertexIndex"))[0]
fmt.Println(ibo)

Вывод будет

[0 2 -4 7 5 -5 4 1 -1 5 2 -2 2 7 -4 0 7 -5 0 1 -3 7 6 -6 4 5 -2 5 6 -3 2 6 -8 0 3 -8]

Вот пример, как я получаю другие атрибуты

ibo := node.FilterName("PolygonVertexIndex")[0].Properties[0].AsInt32Slice()
vbo := node.FilterName("Vertices")[0].Properties[0].AsFloat64Slice()
normals := node.FilterName("Normals")[0].Properties[0].AsFloat64Slice()
uvIndex := node.FilterName("UVIndex")[0].Properties[0].AsInt32Slice()
uv := node.FilterName("UV")[0].Properties[0].AsFloat64Slice()

numFaces := len(ibo) / 3
for f := 0; f < numFaces; f++ {
    face := &Face{}

    index := f * 3
    a := int(ibo[index+0])
    b := int(ibo[index+1])
    c := int(ibo[index+2])*-1 - 1

    face.a.Position = getVec3(vbo, a)
    face.b.Position = getVec3(vbo, b)
    face.c.Position = getVec3(vbo, c)

    uva := int(uvIndex[index+0])
    uvb := int(uvIndex[index+1])
    uvc := int(uvIndex[index+2])
    face.a.UV = getVec2(uv, uva)
    face.b.UV = getVec2(uv, uvb)
    face.c.UV = getVec2(uv, uvc)

    face.a.Normal = getVec3(normals, f*3+0)
    face.b.Normal = getVec3(normals, f*3+1)
    face.c.Normal = getVec3(normals, f*3+2)

    faces[f] = face
}

type Vec3 struct {
    X, Y, Z float32
}
type Vec2 struct {
    X, Y float32
}
type Vertex struct {
    Position *Vec3
    Normal   *Vec3
    Color    *Vec3
    UV       *Vec2
}

type Face struct {
    a vertex.Vertex
    b vertex.Vertex
    c vertex.Vertex
}

func getVec3(data []float64, index int) *Vec3 {
    i := index * 3
    x := float32(data[i])
    y := float32(data[i+1])
    z := float32(data[i+2])
    return &Vec3{x, y, z}
}
0 голосов
/ 24 августа 2018

Возможно, вы просто захотите ioutil.ReadFile(...)?:

import "io/ioutil"

// ...

bs, err := ioutil.ReadFile("./myfile.fbx")
if err != nil {
  panic(err) // TODO: handle error?
}
// now "bs" has all the bytes in the file...
fmt.Printf("OK: read %d byte(s)\n", len(bs))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...