[1114] | 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 | }
|
---|