-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcluster.go
124 lines (109 loc) · 3.32 KB
/
cluster.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package ofbx
import (
"fmt"
"github.com/pkg/errors"
)
// Cluster is an entity which acts on a subset of a geometry's control points
// For each control point that the cluster acts on, the intensity of the cluster's action is modulated by a weight. The link mode (ELinkMode) specifies how the weights are taken into account.
type Cluster struct {
Object
Link Obj
Skin *Skin
Indices []int
Weights []float64
Transform Matrix
TransformLink Matrix
}
// NewCluster creates a new empty Cluster object
func NewCluster(scene *Scene, element *Element) *Cluster {
c := Cluster{}
c.Object = *NewObject(scene, element)
return &c
}
// String pretty formats the Cluster for printing
func (c *Cluster) String() string {
return c.stringPrefix("")
}
// stringPrefix pretty formats the Cluster while respecting the given prefix indentation
func (c *Cluster) stringPrefix(prefix string) string {
s := prefix + "Cluster:" + "\n"
s += c.Object.stringPrefix(prefix + "\t")
s += prefix + "link:" + "\n" + c.Link.stringPrefix(prefix+"\t")
s += prefix + "indices:" + fmt.Sprintf("%v", c.Indices) + "," + "\n"
s += prefix + "weights:" + fmt.Sprintf("%v", c.Weights) + "," + "\n"
s += prefix + "transform_matrix:" + fmt.Sprintf("%v", c.Transform) + "," + "\n"
s += prefix + "transform_link_matrix:" + fmt.Sprintf("%v", c.TransformLink) + "," + "\n"
return s
}
// Type returns CLUSTER
func (c *Cluster) Type() Type {
return CLUSTER
}
// postProcess adds the additional fields that clusters have over just object fields.
// In this case its setting up indicies and weights
func (c *Cluster) postProcess() bool {
element := c.Element()
geom, ok := resolveObjectLinkReverse(c.Skin, GEOMETRY).(*Geometry)
if !ok {
return false
}
var oldIndices []int
var err error
prop := findChildProperty(element, "Indexes")
if prop != nil {
if oldIndices, err = parseBinaryArrayInt(prop[0]); err != nil {
return false
}
}
var oldWeights []float64
prop = findChildProperty(element, "Weights")
if prop != nil {
if oldWeights, err = parseBinaryArrayFloat64(prop[0]); err != nil {
return false
}
}
iLen := len(oldIndices)
if iLen != len(oldWeights) {
return false
}
c.Weights = make([]float64, 0, iLen)
c.Indices = make([]int, 0, iLen)
for i := 0; i < iLen; i++ {
n := &geom.newVerts[oldIndices[i]] //was a geometryimpl NewVertex
if n.index == -1 {
continue // skip vertices which aren't indexed.
}
for n != nil {
c.Indices = append(c.Indices, n.index)
c.Weights = append(c.Weights, oldWeights[i])
n = n.next
}
}
return true
}
func parseCluster(scene *Scene, element *Element) (*Cluster, error) {
obj := NewCluster(scene, element)
prop := findChildProperty(element, "TransformLink")
if prop != nil {
mx, err := parseArrayRawFloat64(prop[0])
if err != nil {
return nil, errors.Wrap(err, "Failed to parse TransformLink")
}
obj.TransformLink, err = matrixFromSlice(mx)
if err != nil {
return nil, errors.Wrap(err, "Failed to parse TransformLink")
}
}
prop = findChildProperty(element, "Transform")
if prop != nil {
mx, err := parseArrayRawFloat64(prop[0])
if err != nil {
return nil, errors.Wrap(err, "Failed to parse TransformLink")
}
obj.Transform, err = matrixFromSlice(mx)
if err != nil {
return nil, errors.Wrap(err, "Failed to parse TransformLink")
}
}
return obj, nil
}