1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using Oni.Collections;
|
---|
4 |
|
---|
5 | namespace Oni.Dae
|
---|
6 | {
|
---|
7 | internal class AxisConverter
|
---|
8 | {
|
---|
9 | private Scene scene;
|
---|
10 | private Axis fromUpAxis;
|
---|
11 | private Axis toUpAxis;
|
---|
12 | private Set<float[]> convertedValues;
|
---|
13 |
|
---|
14 | public static void Convert(Scene scene, Axis fromUpAxis, Axis toUpAxis)
|
---|
15 | {
|
---|
16 | var converter = new AxisConverter {
|
---|
17 | scene = scene,
|
---|
18 | fromUpAxis = fromUpAxis,
|
---|
19 | toUpAxis = toUpAxis,
|
---|
20 | convertedValues = new Set<float[]>()
|
---|
21 | };
|
---|
22 |
|
---|
23 | converter.Convert();
|
---|
24 | }
|
---|
25 |
|
---|
26 | private void Convert()
|
---|
27 | {
|
---|
28 | Convert(scene);
|
---|
29 | }
|
---|
30 |
|
---|
31 | private void Convert(Node node)
|
---|
32 | {
|
---|
33 | foreach (var transform in node.Transforms)
|
---|
34 | Convert(transform);
|
---|
35 |
|
---|
36 | foreach (var instance in node.Instances)
|
---|
37 | Convert(instance);
|
---|
38 |
|
---|
39 | foreach (var child in node.Nodes)
|
---|
40 | Convert(child);
|
---|
41 | }
|
---|
42 |
|
---|
43 | private void Convert(Instance instance)
|
---|
44 | {
|
---|
45 | var geometryInstance = instance as GeometryInstance;
|
---|
46 |
|
---|
47 | if (geometryInstance != null)
|
---|
48 | {
|
---|
49 | Convert(geometryInstance.Target);
|
---|
50 | return;
|
---|
51 | }
|
---|
52 | }
|
---|
53 |
|
---|
54 | private void Convert(Geometry geometry)
|
---|
55 | {
|
---|
56 | foreach (var primitives in geometry.Primitives)
|
---|
57 | {
|
---|
58 | //
|
---|
59 | // HACK: this assumes that position and normal sources are never reused with other semantic
|
---|
60 | //
|
---|
61 |
|
---|
62 | foreach (var input in primitives.Inputs)
|
---|
63 | {
|
---|
64 | if (input.Semantic == Semantic.Position || input.Semantic == Semantic.Normal)
|
---|
65 | ConvertPosition(input.Source.FloatData, input.Source.Stride);
|
---|
66 | }
|
---|
67 | }
|
---|
68 | }
|
---|
69 |
|
---|
70 | private void Convert(Transform transform)
|
---|
71 | {
|
---|
72 | var scale = transform as TransformScale;
|
---|
73 |
|
---|
74 | if (scale != null)
|
---|
75 | {
|
---|
76 | ConvertScale(scale.Values, 3);
|
---|
77 |
|
---|
78 | if (transform.HasAnimations)
|
---|
79 | ConvertScaleAnimation(transform);
|
---|
80 |
|
---|
81 | return;
|
---|
82 | }
|
---|
83 |
|
---|
84 | var rotate = transform as TransformRotate;
|
---|
85 |
|
---|
86 | if (rotate != null)
|
---|
87 | {
|
---|
88 | //ConvertPosition(rotate.Values, 3);
|
---|
89 |
|
---|
90 | if (transform.HasAnimations)
|
---|
91 | ConvertRotationAnimation(transform);
|
---|
92 |
|
---|
93 | return;
|
---|
94 | }
|
---|
95 |
|
---|
96 | var translate = transform as TransformTranslate;
|
---|
97 |
|
---|
98 | if (translate != null)
|
---|
99 | {
|
---|
100 | ConvertPosition(translate.Values, 3);
|
---|
101 |
|
---|
102 | if (transform.HasAnimations)
|
---|
103 | ConvertPositionAnimation(transform);
|
---|
104 |
|
---|
105 | return;
|
---|
106 | }
|
---|
107 |
|
---|
108 | var matrix = transform as TransformMatrix;
|
---|
109 |
|
---|
110 | if (matrix != null)
|
---|
111 | {
|
---|
112 | ConvertMatrix(matrix);
|
---|
113 |
|
---|
114 | //
|
---|
115 | // TODO: matrix animation???
|
---|
116 | //
|
---|
117 |
|
---|
118 | return;
|
---|
119 | }
|
---|
120 | }
|
---|
121 |
|
---|
122 | private void ConvertMatrix(TransformMatrix transform)
|
---|
123 | {
|
---|
124 | if (fromUpAxis == Axis.Z && toUpAxis == Axis.Y)
|
---|
125 | {
|
---|
126 | Matrix zm = transform.Matrix;
|
---|
127 | Matrix ym = zm;
|
---|
128 | //Matrix ym = Matrix.CreateRotationX(
|
---|
129 | // MathHelper.PiOver2) *
|
---|
130 | //zm *
|
---|
131 | //Matrix.CreateRotationX(
|
---|
132 | // -MathHelper.PiOver2);
|
---|
133 | ym.M12 = zm.M13;
|
---|
134 | ym.M13 = -zm.M12;
|
---|
135 | ym.M21 = zm.M31;
|
---|
136 | ym.M22 = zm.M33;
|
---|
137 | ym.M23 = -zm.M32;
|
---|
138 | ym.M31 = -zm.M21;
|
---|
139 | ym.M32 = -zm.M23;
|
---|
140 | ym.M33 = zm.M22;
|
---|
141 | ym.M42 = zm.M43;
|
---|
142 | ym.M43 = -zm.M42;
|
---|
143 | transform.Matrix = ym;
|
---|
144 | }
|
---|
145 | //else if (fromUpAxis == Axis.Y && toUpAxis == Axis.Z)
|
---|
146 | //{
|
---|
147 | // rotate.XAxis = new Vector3(1.0f, 0.0f, 0.0f);
|
---|
148 | // rotate.YAxis = new Vector3(0.0f, 0.0f, -1.0f);
|
---|
149 | // rotate.ZAxis = new Vector3(0.0f, 1.0f, 0.0f);
|
---|
150 | //}
|
---|
151 | //else if (fromUpAxis == Axis.X && toUpAxis == Axis.Y)
|
---|
152 | //{
|
---|
153 | // rotate.XAxis = new Vector3(0.0f, 0.0f, -1.0f);
|
---|
154 | // rotate.YAxis = new Vector3(1.0f, 0.0f, 1.0f);
|
---|
155 | // rotate.ZAxis = new Vector3(0.0f, 1.0f, 0.0f);
|
---|
156 | //}
|
---|
157 | }
|
---|
158 |
|
---|
159 | private void ConvertPosition(float[] values, int stride)
|
---|
160 | {
|
---|
161 | if (!convertedValues.Add(values))
|
---|
162 | return;
|
---|
163 |
|
---|
164 | for (int i = 0; i + stride - 1 < values.Length; i += stride)
|
---|
165 | Convert(values, i, f => -f);
|
---|
166 | }
|
---|
167 |
|
---|
168 | private void ConvertPositionAnimation(Transform transform)
|
---|
169 | {
|
---|
170 | Convert(transform.Animations, 0, s => s != null ? s.Scale(-1.0f) : null);
|
---|
171 | }
|
---|
172 |
|
---|
173 | private void ConvertRotationAnimation(Transform transform)
|
---|
174 | {
|
---|
175 | ConvertPositionAnimation(transform);
|
---|
176 | }
|
---|
177 |
|
---|
178 | private void ConvertScale(float[] values, int stride)
|
---|
179 | {
|
---|
180 | for (int i = 0; i + stride - 1 < values.Length; i += stride)
|
---|
181 | Convert(values, i, null);
|
---|
182 | }
|
---|
183 |
|
---|
184 | private void ConvertScaleAnimation(Transform transform)
|
---|
185 | {
|
---|
186 | Convert(transform.Animations, 0, null);
|
---|
187 | }
|
---|
188 |
|
---|
189 | private void Convert<T>(IList<T> list, int baseIndex, Func<T, T> negate)
|
---|
190 | {
|
---|
191 | T t0 = list[baseIndex + 0];
|
---|
192 | T t1 = list[baseIndex + 1];
|
---|
193 | T t2 = list[baseIndex + 2];
|
---|
194 |
|
---|
195 | if (fromUpAxis == Axis.Z && toUpAxis == Axis.Y)
|
---|
196 | {
|
---|
197 | list[baseIndex + 0] = t0;
|
---|
198 | list[baseIndex + 1] = t2;
|
---|
199 | list[baseIndex + 2] = negate != null ? negate(t1) : t1;
|
---|
200 | }
|
---|
201 | else if (fromUpAxis == Axis.Y && toUpAxis == Axis.Z)
|
---|
202 | {
|
---|
203 | list[baseIndex + 0] = t0;
|
---|
204 | list[baseIndex + 1] = negate != null ? negate(t2) : t2;
|
---|
205 | list[baseIndex + 2] = t1;
|
---|
206 | }
|
---|
207 | else if (fromUpAxis == Axis.X && toUpAxis == Axis.Y)
|
---|
208 | {
|
---|
209 | list[baseIndex + 0] = negate != null ? negate(t2) : t2;
|
---|
210 | list[baseIndex + 1] = t0;
|
---|
211 | list[baseIndex + 2] = t1;
|
---|
212 | }
|
---|
213 | }
|
---|
214 | }
|
---|
215 | }
|
---|