-
Notifications
You must be signed in to change notification settings - Fork 0
/
PrimitiveMover.java
92 lines (82 loc) · 2.55 KB
/
PrimitiveMover.java
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
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
public class PrimitiveMover implements PrimitiveModifier, JSONSerializable {
PrimitiveMover(){
method = MoveMethod.MM_LINEAR;
}
PrimitiveMover(ScenePrimitive sp){
prim=sp;
method = MoveMethod.MM_LINEAR;
}
public void setPrimitive(ScenePrimitive sp){
prim=(ZSprite)sp;
}
public PrimitiveModifier clone(ScenePrimitive sp){
PrimitiveMover pm = new PrimitiveMover(sp);
pm.velocity = velocity;
pm.method = method;
for (Vector3i v: positions)
pm.positions.add(v.clone());
return pm;
}
public enum MoveMethod {MM_LINEAR, MM_BSPLINE};
public ArrayList<Vector3i> positions=new ArrayList<Vector3i>();
public float velocity;
public MoveMethod method;
public float time;
public ScenePrimitive prim;
public void calculate(double timeStep){
if (positions.size()<2) return;
final int pointsToUse=4;
time+=timeStep*velocity/1000.0f;
int splineN=positions.size();
while (time>splineN) time-=splineN;
while (time<0) time+=splineN;
int part=(int)Math.floor(time);
float partTime=time-part;
switch (method) {
case MM_LINEAR:
prim.moveTo(positions.get(part).toVec3d().cloneBlend(1-partTime, positions.get((part+1)%splineN)).toVec3i());
break;
case MM_BSPLINE:
Vector3d newPos=new Vector3d();
for (int i=part;i<part+pointsToUse;i++){
int ai = i % splineN;
newPos.add(positions.get(ai).cloneMultiply(bezier(pointsToUse, i-part, partTime)));
}
prim.moveTo(newPos.toVec3i());
break;
}
}
protected float bezier(int n, int k, float f){
int fac=1;
for (int i=k+1;i<=n;i++) fac*=i;
for (int i=1;i<=n-k;i++) fac/=i;
return (float)(fac*Math.pow(f, k)*Math.pow(1-f,n-k));
}
public Map<String, Object> jsonSerialize() {
TreeMap<String,Object> tm = new TreeMap<String,Object>();
tm.put("type", "PrimitiveMover");
tm.put("positions", positions);
tm.put("velocity", velocity);
tm.put("method", method==MoveMethod.MM_LINEAR?"linear":(
method==MoveMethod.MM_BSPLINE?"bspline":""));
return tm;
}
public void jsonDeserialize(Object obj) {
Map<String, Object> map=(Map<String, Object>) obj;
ArrayList<Object> pos = (ArrayList<Object>)map.get("positions");
positions.clear();
for (Object p: pos) {
Vector3i v=new Vector3i();
v.jsonDeserialize(p);
positions.add(v);
}
velocity=((Number) map.get("velocity")).floatValue();
String m=(String)map.get("method");
if (m.equals("linear")) method=MoveMethod.MM_LINEAR;
else if (m.equals("bspline")) method=MoveMethod.MM_BSPLINE;
}
}