65d581f9d5cce15645948c31a8fb6070a79fc8d7
[anneal.git] / src / edu / berkeley / qfat / geom / HasBindingGroup.java
1 package edu.berkeley.qfat.geom;
2 import javax.media.opengl.*;
3 import java.util.*;
4 import edu.berkeley.qfat.Mesh;
5
6 public abstract class HasBindingGroup {
7
8     public BindingGroup bindingGroup;
9
10     // know:      self   = bindingGroup[self] * master
11     // know:      other  = other.bindingGroup[other] * other.bindingGroup.master
12     // want:      self   = bindingMatrix * other
13     // therefore: master = bindingGroup[self]^-1 * bindingMatrix * other
14     // therefore:        = bindingGroup[self]^-1 * bindingMatrix * other.bindingGroup[other] * other.bindingGroup.master
15     public void bindTo(Matrix bindingMatrix, HasBindingGroup other) {
16         if (bindingGroup == null) bindingGroup = new BindingGroup(this);
17         if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
18
19         if (other.bindingGroup == this.bindingGroup) {
20             if (getBindingMatrix(other).equals(bindingMatrix))
21                 return;
22             /*
23             if (this instanceof Mesh.E)
24                 throw new Error("rebind attempt: "+this+" and "+other+" with "
25                                 + bindingMatrix
26                                 + "; expected "
27                                 + getBindingMatrix(other));
28             */
29             setConstraint(bindingMatrix);
30             /*
31               System.err.println("WARNING: discarding rebind attempt: "+this+" and "+other+m);
32             */
33             //" with "
34             //+ bindingMatrix
35             //+ "; expected "
36             //+ getBindingMatrix(other));
37             return;
38         }
39
40
41         bindingMatrix =
42             getBindingMatrix().inverse()
43             .times(bindingMatrix)
44             .times(other.getBindingMatrix());
45         other.bindingGroup.merge(bindingGroup, bindingMatrix);
46     }
47
48     public int bindingGroupSize() {
49         if (bindingGroup == null) return 1;
50         return bindingGroup.size();
51     }
52
53
54     public Matrix getBindingMatrix() {
55         if (bindingGroup==null) return Matrix.ONE;
56         return bindingGroup.getMatrix(this);
57     }
58
59     public Matrix getBindingMatrix(HasBindingGroup other) {
60         if (other==this) return Matrix.ONE;
61         return bindingGroup.getMatrix(this, other);
62     }
63
64     public HasBindingGroup getMaster() {
65         if (bindingGroup==null) return this;
66         return bindingGroup.getMaster();
67     }
68
69     public Matrix getConstraint() {
70         if (bindingGroup==null) return Matrix.ONE;
71         Matrix v = getBindingMatrix(getMaster());
72         return v.inverse().times(bindingGroup.krank).times(v);
73     }
74     public void setConstraint(Matrix m) {
75         if (bindingGroup==null) bindingGroup = new BindingGroup(this);
76         Matrix v = getBindingMatrix(getMaster());
77         bindingGroup.krank = bindingGroup.krank.times(v.inverse().times(m).times(v));
78     }
79
80     public void unbind() {
81         if (bindingGroup==null) return;
82         bindingGroup.unbind(this);
83         bindingGroup = null;
84         bindingGroupChanged(bindingGroup);
85     }
86
87     public boolean isBoundTo(HasBindingGroup t) {
88         return t==this || (bindingGroup!=null && bindingGroup.contains(t));
89     }
90
91     public Iterable getBoundPeers() {
92         if (bindingGroup==null) bindingGroup = new BindingGroup(this);
93         return bindingGroup;
94     }
95     public void bindingGroupChanged(BindingGroup newBindingGroup) { }
96 }