This commit is contained in:
dengqn 2024-06-06 14:55:35 +08:00
parent 5041e92871
commit 7acdc03776
7 changed files with 40 additions and 333 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.gltf

View File

@ -15,6 +15,7 @@ func Convert(stl STL, outFile string) {
normalBuf := make([]byte, 0) normalBuf := make([]byte, 0)
positionBuf := make([]byte, 0) positionBuf := make([]byte, 0)
// padding each buffer part
padding := func(buf []byte) []byte { padding := func(buf []byte) []byte {
log.Println("padding: ", len(buf)%4) log.Println("padding: ", len(buf)%4)
for len(buf)%4 != 0 { for len(buf)%4 != 0 {
@ -24,22 +25,23 @@ func Convert(stl STL, outFile string) {
return buf return buf
} }
// 写入顶点 // positions to byte
for i := range stl.TriangleNum { for i := range stl.TriangleNum {
t := stl.Triangles[i] t := stl.Triangles[i]
positionBuf = append(positionBuf, t.Position...) positionBuf = append(positionBuf, t.Position...)
} }
positionBuf = padding(positionBuf) positionBuf = padding(positionBuf)
// 写入法向量 // normals to byte
for i := range stl.TriangleNum { for i := range stl.TriangleNum {
t := stl.Triangles[i] t := stl.Triangles[i]
// each position, write 3 times
normalBuf = append(normalBuf, t.Normal...) normalBuf = append(normalBuf, t.Normal...)
normalBuf = append(normalBuf, t.Normal...) normalBuf = append(normalBuf, t.Normal...)
normalBuf = append(normalBuf, t.Normal...) normalBuf = append(normalBuf, t.Normal...)
} }
normalBuf = padding(normalBuf) normalBuf = padding(normalBuf)
// 写入索引 // indices to byte
for i := range stl.TriangleNum * 3 { for i := range stl.TriangleNum * 3 {
buf := make([]byte, 4) buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, uint32(i)) binary.LittleEndian.PutUint32(buf, uint32(i))
@ -49,22 +51,24 @@ func Convert(stl STL, outFile string) {
log.Println(len(positionBuf), len(normalBuf), len(indexBuf)) log.Println(len(positionBuf), len(normalBuf), len(indexBuf))
// concat
allData := make([]byte, 0) allData := make([]byte, 0)
allData = append(allData, indexBuf...) allData = append(allData, indexBuf...) // Indices: 0
allData = append(allData, normalBuf...) allData = append(allData, normalBuf...) // attributes["NORMAL"] = 1
allData = append(allData, positionBuf...) allData = append(allData, positionBuf...) // attributes["POSITION"] = 2
base := base64.StdEncoding.EncodeToString(allData) base := base64.StdEncoding.EncodeToString(allData)
attributes := make(map[string]int, 0) attributes := make(map[string]int, 0)
attributes["POSITION"] = 2
attributes["NORMAL"] = 1 attributes["NORMAL"] = 1
attributes["POSITION"] = 2
gltf := GLTF{ gltf := GLTF{
Asset: Asset{Version: "2.0"}, Asset: Asset{Version: "2.0"},
Scenes: []Scene{{Nodes: []int{0}}}, Scenes: []Scene{{Nodes: []int{0}}},
Nodes: []Node{{Mesh: 0}}, Nodes: []Node{{Mesh: 0}},
Meshes: []Mesh{{Primitives: []Primitive{{Attributes: attributes, Indices: 0, Mode: 4}}}}, Meshes: []Mesh{{Primitives: []Primitive{{Attributes: attributes, Indices: 0, Mode: 4}}}},
// ByteLength not length after base64
Buffers: []Buffer{{Uri: fmt.Sprintf("data:application/gltf-buffer;base64,%s", base), ByteLength: len(allData)}}, Buffers: []Buffer{{Uri: fmt.Sprintf("data:application/gltf-buffer;base64,%s", base), ByteLength: len(allData)}},
BufferViews: []BufferView{ BufferViews: []BufferView{
// index // index
@ -72,58 +76,58 @@ func Convert(stl STL, outFile string) {
Buffer: 0, Buffer: 0,
ByteOffset: 0, ByteOffset: 0,
ByteLength: len(indexBuf), ByteLength: len(indexBuf),
Target: 34963, Target: 34963, // ELEMENT_ARRAY_BUFFER float indices
}, },
// normal // normal
{ {
Buffer: 0, Buffer: 0,
ByteOffset: len(indexBuf), ByteOffset: len(indexBuf),
ByteLength: len(normalBuf), ByteLength: len(normalBuf),
Target: 34962, Target: 34962, // ARRAY_BUFFER int vertex
}, },
// position // position
{ {
Buffer: 0, Buffer: 0,
// ByteOffset: len(indexBuf),
ByteOffset: len(indexBuf) + len(normalBuf), ByteOffset: len(indexBuf) + len(normalBuf),
ByteLength: len(positionBuf), ByteLength: len(positionBuf),
Target: 34962, Target: 34962, // ARRAY_BUFFER int vertex
}, },
}, },
Accessors: []Accessor{ Accessors: []Accessor{
{ {
BufferView: 0, BufferView: 0,
ByteOffset: 0, ByteOffset: 0,
ComponentType: 5125, ComponentType: 5125, // uint ; 5124 int will loss model parts
Type: "SCALAR", Type: "SCALAR", // index
Count: stl.TriangleNum * 3, Count: stl.TriangleNum * 3, // 1 index : 1 position
}, },
{ {
BufferView: 1, BufferView: 1,
ByteOffset: 0, ByteOffset: 0,
ComponentType: 5126, ComponentType: 5126, // float
Type: "VEC3", Type: "VEC3",
Count: stl.TriangleNum * 3, Count: stl.TriangleNum * 3, // 1 normal : 1 position
Max: []float32{1, 1, 1}, Max: []float32{1, 1, 1}, // or cal from stl data
Min: []float32{-1, -1, -1}, Min: []float32{-1, -1, -1},
}, },
{ {
BufferView: 2, BufferView: 2,
ByteOffset: 0, ByteOffset: 0,
ComponentType: 5126, ComponentType: 5126, // float
Type: "VEC3", Type: "VEC3",
Count: len(positionBuf) / 12, Count: len(positionBuf) / 12,// xyz = 4x3; or stl.TriangleNum * 3
Max: stl.Max, Max: stl.Max, // cal from stl data
Min: stl.Min, Min: stl.Min,
}, },
}, },
} }
// or not indent
data, err := json.MarshalIndent(gltf, " ", " ") data, err := json.MarshalIndent(gltf, " ", " ")
if err != nil { if err != nil {
log.Println("marshal error: ", err.Error()) log.Println("marshal error: ", err.Error())
return return
} }
// output
os.Remove(outFile) os.Remove(outFile)
f, err := os.OpenFile(outFile, os.O_CREATE, os.ModePerm) f, err := os.OpenFile(outFile, os.O_CREATE, os.ModePerm)
if err != nil { if err != nil {

19
data.go
View File

@ -11,18 +11,17 @@ type Triangle struct {
XYZ []float32 XYZ []float32
} }
func (t Triangle) EuqalsPosition(position []byte) bool {
x1 := binary.LittleEndian.Uint32(position[:4])
y1 := binary.LittleEndian.Uint32(position[4:8])
z1 := binary.LittleEndian.Uint32(position[8:12])
x2 := binary.LittleEndian.Uint32(t.Position[:4]) //
y2 := binary.LittleEndian.Uint32(t.Position[4:8]) // header num
z2 := binary.LittleEndian.Uint32(t.Position[8:12]) // |----80B------|-4B-|-----triangle1--------|--------triangle2-------|-----------...
return x1 == x2 && y1 == y2 && z1 == z2
}
// Normal(xyz) 4 x 3 position1 position2 position3 attribute
// each triangle: |--------12--------|--------12--------|--------12--------|--------12--------|---2-------|
//
//
//
//
type STL struct { type STL struct {
Header string Header string
TriangleNum int TriangleNum int

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,8 +12,11 @@ func Load(filePath string) (stl STL) {
if err != nil { if err != nil {
log.Panic("open file " + filePath + " error: " + err.Error()) log.Panic("open file " + filePath + " error: " + err.Error())
} }
// load 80 header
headerBuf := make([]byte, 80) headerBuf := make([]byte, 80)
file.Read(headerBuf) file.Read(headerBuf)
// int32
triangleNumBuf := make([]byte, 4) triangleNumBuf := make([]byte, 4)
file.Read(triangleNumBuf) file.Read(triangleNumBuf)
@ -30,7 +33,7 @@ func Load(filePath string) (stl STL) {
positionBuf := make([]byte, 4*3*3) positionBuf := make([]byte, 4*3*3)
file.Read(positionBuf) file.Read(positionBuf)
// find max/min xyz
for r := range 3 { for r := range 3 {
x := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[:4+(r*4)])) x := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[:4+(r*4)]))
y := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r * 4) : (r*4)+4])) y := math.Float32frombits(binary.LittleEndian.Uint32(positionBuf[(r * 4) : (r*4)+4]))