comments
This commit is contained in:
parent
5041e92871
commit
7acdc03776
|
@ -0,0 +1 @@
|
||||||
|
*.gltf
|
48
convert.go
48
convert.go
|
@ -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
19
data.go
|
@ -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
5
load.go
5
load.go
|
@ -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]))
|
||||||
|
|
Loading…
Reference in New Issue