1 | package com.framsticks.model; |
---|
2 | |
---|
3 | import java.util.ArrayList; |
---|
4 | import java.util.Arrays; |
---|
5 | import java.util.Iterator; |
---|
6 | import java.util.List; |
---|
7 | |
---|
8 | import com.framsticks.model.f0.Schema; |
---|
9 | import com.framsticks.params.ParamsUtil; |
---|
10 | import com.framsticks.params.annotations.AutoAppendAnnotation; |
---|
11 | import com.framsticks.params.annotations.FramsClassAnnotation; |
---|
12 | // import com.framsticks.params.annotations.ParamAnnotation; |
---|
13 | import com.framsticks.parsers.F0Parser; |
---|
14 | import com.framsticks.util.AutoBuilder; |
---|
15 | import com.framsticks.util.FramsticksException; |
---|
16 | import com.framsticks.util.ResourceBuilder; |
---|
17 | import com.framsticks.util.lang.Casting; |
---|
18 | import com.framsticks.util.lang.IterableIterator; |
---|
19 | import com.framsticks.util.math.Orientation; |
---|
20 | |
---|
21 | @FramsClassAnnotation |
---|
22 | public class ModelBuilder extends ResourceBuilder<Model> implements AutoBuilder { |
---|
23 | |
---|
24 | Schema schema; |
---|
25 | final List<ModelComponent> components = new ArrayList<>(); |
---|
26 | |
---|
27 | @Override |
---|
28 | public Model finish() { |
---|
29 | if (stream == null && components.isEmpty()) { |
---|
30 | throw new FramsticksException().msg("model builder instance not ready"); |
---|
31 | } |
---|
32 | if (stream != null) { |
---|
33 | if (schema == null) { |
---|
34 | schema = Schema.getDefaultSchema(); |
---|
35 | } |
---|
36 | F0Parser parser = new F0Parser(schema, stream); |
---|
37 | components.addAll(ParamsUtil.stripAccess(parser.parse(), ModelComponent.class)); |
---|
38 | } |
---|
39 | return build(); |
---|
40 | } |
---|
41 | |
---|
42 | /** |
---|
43 | * @return the schema |
---|
44 | */ |
---|
45 | public Schema getSchema() { |
---|
46 | return schema; |
---|
47 | } |
---|
48 | |
---|
49 | /** |
---|
50 | * @param schema the schema to set |
---|
51 | */ |
---|
52 | @AutoAppendAnnotation |
---|
53 | public ModelBuilder schema(Schema schema) { |
---|
54 | this.schema = schema; |
---|
55 | return this; |
---|
56 | } |
---|
57 | |
---|
58 | @AutoAppendAnnotation |
---|
59 | public ModelBuilder addComponent(ModelComponent component) { |
---|
60 | components.add(component); |
---|
61 | return this; |
---|
62 | } |
---|
63 | |
---|
64 | @AutoAppendAnnotation |
---|
65 | public ModelBuilder addComponents(List<ModelComponent> component) { |
---|
66 | this.components.addAll(component); |
---|
67 | return this; |
---|
68 | } |
---|
69 | |
---|
70 | public Model build() { |
---|
71 | Iterator<ModelComponent> i = components.iterator(); |
---|
72 | if (!i.hasNext()) { |
---|
73 | throw new FramsticksException().msg("empty components list"); |
---|
74 | } |
---|
75 | Model f0Genotype = Casting.tryCast(Model.class, i.next()); |
---|
76 | if (f0Genotype == null) { |
---|
77 | throw new FramsticksException().msg("first component is not a Model"); |
---|
78 | } |
---|
79 | for (ModelComponent component : new IterableIterator<ModelComponent>(i)) { |
---|
80 | if (component instanceof Joint) { |
---|
81 | f0Genotype.joints.add((Joint)component); |
---|
82 | continue; |
---|
83 | } |
---|
84 | if (component instanceof Part) { |
---|
85 | f0Genotype.parts.add((Part)component); |
---|
86 | continue; |
---|
87 | } |
---|
88 | if (component instanceof NeuroDefinition) { |
---|
89 | f0Genotype.neuroDefinitions.add((NeuroDefinition) component); |
---|
90 | continue; |
---|
91 | } |
---|
92 | if (component instanceof NeuroConnection) { |
---|
93 | f0Genotype.neuroConnections.add((NeuroConnection) component); |
---|
94 | continue; |
---|
95 | } |
---|
96 | throw new FramsticksException().msg("invalid class").arg("class", component.getClass().getCanonicalName()); |
---|
97 | } |
---|
98 | |
---|
99 | for (Part p : f0Genotype.getParts()) { |
---|
100 | p.setOrientation(new Orientation().rotate(p.getRotation())); |
---|
101 | } |
---|
102 | for (Joint j : f0Genotype.getJoints()) { |
---|
103 | /** based on c++ Joint::attachToParts*/ |
---|
104 | Part p1 = f0Genotype.parts.get(j.part1); |
---|
105 | Part p2 = f0Genotype.parts.get(j.part2); |
---|
106 | assert p1 != null && p2 != null; |
---|
107 | Orientation o = new Orientation().rotate(j.getRotation()); |
---|
108 | p2.setOrientation(p1.getOrientation().transform(o)); |
---|
109 | p2.setPosition(p2.getOrientation().transform(j.getDelta()).add(p1.getPosition())); |
---|
110 | } |
---|
111 | return f0Genotype; |
---|
112 | } |
---|
113 | |
---|
114 | @Override |
---|
115 | public List<Object> autoFinish() { |
---|
116 | Model model = finish(); |
---|
117 | assert schema != null; |
---|
118 | return Arrays.asList(schema.getRegistry(), model); |
---|
119 | } |
---|
120 | |
---|
121 | } |
---|