| 1 | using System; | 
 
 
 
 
 | 2 | using System.Collections.Generic; | 
 
 
 
 
 | 3 | using Oni.Collections; | 
 
 
 
 
 | 4 |  | 
 
 
 
 
 | 5 | namespace Oni.Dae | 
 
 
 
 
 | 6 | { | 
 
 
 
 
 | 7 | internal class UnitConverter | 
 
 
 
 
 | 8 | { | 
 
 
 
 
 | 9 | private Scene scene; | 
 
 
 
 
 | 10 | private float scale; | 
 
 
 
 
 | 11 | private Set<float[]> scaledValues; | 
 
 
 
 
 | 12 |  | 
 
 
 
 
 | 13 | public static void Convert(Scene scene, float scale) | 
 
 
 
 
 | 14 | { | 
 
 
 
 
 | 15 | var converter = new UnitConverter { | 
 
 
 
 
 | 16 | scene = scene, | 
 
 
 
 
 | 17 | scale = scale, | 
 
 
 
 
 | 18 | scaledValues = new Set<float[]>() | 
 
 
 
 
 | 19 | }; | 
 
 
 
 
 | 20 |  | 
 
 
 
 
 | 21 | converter.Convert(); | 
 
 
 
 
 | 22 | } | 
 
 
 
 
 | 23 |  | 
 
 
 
 
 | 24 | private void Convert() | 
 
 
 
 
 | 25 | { | 
 
 
 
 
 | 26 | Convert(scene); | 
 
 
 
 
 | 27 | } | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | private void Convert(Node node) | 
 
 
 
 
 | 30 | { | 
 
 
 
 
 | 31 | foreach (var transform in node.Transforms) | 
 
 
 
 
 | 32 | Convert(transform); | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | foreach (var instance in node.Instances) | 
 
 
 
 
 | 35 | Convert(instance); | 
 
 
 
 
 | 36 |  | 
 
 
 
 
 | 37 | foreach (var child in node.Nodes) | 
 
 
 
 
 | 38 | Convert(child); | 
 
 
 
 
 | 39 | } | 
 
 
 
 
 | 40 |  | 
 
 
 
 
 | 41 | private void Convert(Instance instance) | 
 
 
 
 
 | 42 | { | 
 
 
 
 
 | 43 | var geometryInstance = instance as GeometryInstance; | 
 
 
 
 
 | 44 |  | 
 
 
 
 
 | 45 | if (geometryInstance != null) | 
 
 
 
 
 | 46 | { | 
 
 
 
 
 | 47 | Convert(geometryInstance.Target); | 
 
 
 
 
 | 48 | return; | 
 
 
 
 
 | 49 | } | 
 
 
 
 
 | 50 | } | 
 
 
 
 
 | 51 |  | 
 
 
 
 
 | 52 | private void Convert(Geometry geometry) | 
 
 
 
 
 | 53 | { | 
 
 
 
 
 | 54 | foreach (var primitives in geometry.Primitives) | 
 
 
 
 
 | 55 | { | 
 
 
 
 
 | 56 | // | 
 
 
 
 
 | 57 | // TODO: this assumes that position sources are not reused. | 
 
 
 
 
 | 58 | // | 
 
 
 
 
 | 59 |  | 
 
 
 
 
 | 60 | foreach (var input in primitives.Inputs) | 
 
 
 
 
 | 61 | { | 
 
 
 
 
 | 62 | if (input.Semantic == Semantic.Position) | 
 
 
 
 
 | 63 | Scale(input.Source.FloatData, input.Source.Stride); | 
 
 
 
 
 | 64 | } | 
 
 
 
 
 | 65 | } | 
 
 
 
 
 | 66 | } | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | private void Convert(Transform transform) | 
 
 
 
 
 | 69 | { | 
 
 
 
 
 | 70 | var translate = transform as TransformTranslate; | 
 
 
 
 
 | 71 |  | 
 
 
 
 
 | 72 | if (translate != null) | 
 
 
 
 
 | 73 | { | 
 
 
 
 
 | 74 | Scale(translate.Values, 3); | 
 
 
 
 
 | 75 |  | 
 
 
 
 
 | 76 | if (translate.HasAnimations) | 
 
 
 
 
 | 77 | { | 
 
 
 
 
 | 78 | for (int i = 0; i < translate.Animations.Length; i++) | 
 
 
 
 
 | 79 | { | 
 
 
 
 
 | 80 | Sampler s = translate.Animations[i]; | 
 
 
 
 
 | 81 | translate.Animations[i] = s == null ? null : s.Scale(scale); | 
 
 
 
 
 | 82 | } | 
 
 
 
 
 | 83 | } | 
 
 
 
 
 | 84 |  | 
 
 
 
 
 | 85 | return; | 
 
 
 
 
 | 86 | } | 
 
 
 
 
 | 87 |  | 
 
 
 
 
 | 88 | var matrix = transform as TransformMatrix; | 
 
 
 
 
 | 89 |  | 
 
 
 
 
 | 90 | if (matrix != null) | 
 
 
 
 
 | 91 | { | 
 
 
 
 
 | 92 | matrix.Values[3] *= scale; | 
 
 
 
 
 | 93 | matrix.Values[7] *= scale; | 
 
 
 
 
 | 94 | matrix.Values[11] *= scale; | 
 
 
 
 
 | 95 |  | 
 
 
 
 
 | 96 | return; | 
 
 
 
 
 | 97 | } | 
 
 
 
 
 | 98 | } | 
 
 
 
 
 | 99 |  | 
 
 
 
 
 | 100 | private void Scale(float[] values, int stride) | 
 
 
 
 
 | 101 | { | 
 
 
 
 
 | 102 | if (!scaledValues.Add(values)) | 
 
 
 
 
 | 103 | return; | 
 
 
 
 
 | 104 |  | 
 
 
 
 
 | 105 | for (int i = 0; i + stride - 1 < values.Length; i += stride) | 
 
 
 
 
 | 106 | { | 
 
 
 
 
 | 107 | values[i + 0] *= scale; | 
 
 
 
 
 | 108 | values[i + 1] *= scale; | 
 
 
 
 
 | 109 | values[i + 2] *= scale; | 
 
 
 
 
 | 110 | } | 
 
 
 
 
 | 111 | } | 
 
 
 
 
 | 112 | } | 
 
 
 
 
 | 113 | } |