source: OniSplit/Dae/Converters/AxisConverter.cs@ 1162

Last change on this file since 1162 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 6.5 KB
Line 
1using System;
2using System.Collections.Generic;
3using Oni.Collections;
4
5namespace 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}
Note: See TracBrowser for help on using the repository browser.