d884672ac7109bb0b1ebbca9c5805593dd4bb212
[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
5 public abstract class HasBindingGroup {
6
7     public BindingGroup bindingGroup;
8
9     // know:      self   = bindingGroup[self] * master
10     // know:      other  = other.bindingGroup[other] * other.bindingGroup.master
11     // want:      self   = bindingMatrix * other
12     // therefore: master = bindingGroup[self]^-1 * bindingMatrix * other
13     // therefore:        = bindingGroup[self]^-1 * bindingMatrix * other.bindingGroup[other] * other.bindingGroup.master
14     public void bindTo(Matrix bindingMatrix, HasBindingGroup other) {
15         if (bindingGroup == null) bindingGroup = new BindingGroup(this);
16         if (other.bindingGroup == null) other.bindingGroup = new BindingGroup(other);
17
18         if (other.bindingGroup == this.bindingGroup) {
19             if (getBindingMatrix(other).equals(bindingMatrix))
20                 return;
21             /*
22             throw new Error("rebind attempt: "+this+" and "+other+" with "
23                             + bindingMatrix
24                             + "; expected "
25                             + getBindingMatrix(other));
26             */
27             Matrix vom = other.getBindingMatrix(bindingGroup.getMaster());
28             Matrix v2 = bindingMatrix;
29             Matrix v3 = getBindingMatrix(other);
30             Matrix m = vom.inverse().times(v2.inverse()).times(v3).times(vom);
31             bindingGroup.krank = bindingGroup.krank.times(m);
32             /*
33               System.err.println("WARNING: discarding rebind attempt: "+this+" and "+other+m);
34             */
35             //" with "
36             //+ bindingMatrix
37             //+ "; expected "
38             //+ getBindingMatrix(other));
39             return;
40         }
41
42
43         bindingMatrix =
44             getBindingMatrix().inverse()
45             .times(bindingMatrix)
46             .times(other.getBindingMatrix());
47         other.bindingGroup.merge(bindingGroup, bindingMatrix);
48     }
49
50     public int bindingGroupSize() {
51         if (bindingGroup == null) return 1;
52         return bindingGroup.size();
53     }
54
55
56     public Matrix getBindingMatrix() {
57         if (bindingGroup==null) return Matrix.ONE;
58         return bindingGroup.getMatrix(this);
59     }
60
61     public Matrix getBindingMatrix(HasBindingGroup other) {
62         if (other==this) return Matrix.ONE;
63         return bindingGroup.getMatrix(this, other);
64     }
65
66     public HasBindingGroup getMaster() {
67         if (bindingGroup==null) return this;
68         return bindingGroup.getMaster();
69     }
70
71     public void unbind() {
72         if (bindingGroup==null) return;
73         bindingGroup.unbind(this);
74         bindingGroup = null;
75         bindingGroupChanged(bindingGroup);
76     }
77
78     public boolean isBoundTo(HasBindingGroup t) {
79         return t==this || (bindingGroup!=null && bindingGroup.contains(t));
80     }
81
82     public Iterable getBoundPeers() {
83         if (bindingGroup==null) bindingGroup = new BindingGroup(this);
84         return bindingGroup;
85     }
86     public void bindingGroupChanged(BindingGroup newBindingGroup) { }
87 }