public source MakeColladaUVs(string name, int uvIndex) { EnsureDeduplicationMap(); int index = 0; var uvs = new float[Deduplicator.DeduplicatedUVs[uvIndex].Count * 2]; foreach (var uv in Deduplicator.DeduplicatedUVs[uvIndex]) { uvs[index++] = uv[0]; uvs[index++] = uv[1]; } return(ColladaUtils.MakeFloatSource(name, "uvs" + uvIndex.ToString(), new string[] { "S", "T" }, uvs)); }
public source MakeColladaColors(string name, int setIndex) { EnsureDeduplicationMap(); int index = 0; var colors = new float[Deduplicator.Colors[setIndex].Uniques.Count * 3]; foreach (var color in Deduplicator.Colors[setIndex].Uniques) { colors[index++] = color[0]; colors[index++] = color[1]; colors[index++] = color[2]; } return(ColladaUtils.MakeFloatSource(name, "colors" + setIndex.ToString(), new string[] { "R", "G", "B" }, colors)); }
public source MakeColladaBinormals(string name) { EnsureDeduplicationMap(); int index = 0; var binormals = new float[Deduplicator.Normals.Uniques.Count * 3]; foreach (var ntb in Deduplicator.Normals.Uniques) { var binormal = ntb.Row2; binormals[index++] = binormal[0]; binormals[index++] = binormal[1]; binormals[index++] = binormal[2]; } return(ColladaUtils.MakeFloatSource(name, "binormals", new string[] { "X", "Y", "Z" }, binormals)); }
public source MakeColladaTangents(string name) { EnsureDeduplicationMap(); int index = 0; var tangents = new float[Deduplicator.Normals.Uniques.Count * 3]; foreach (var ntb in Deduplicator.Normals.Uniques) { var tangent = ntb.Row1; tangents[index++] = tangent[0]; tangents[index++] = tangent[1]; tangents[index++] = tangent[2]; } return(ColladaUtils.MakeFloatSource(name, "tangents", new string[] { "X", "Y", "Z" }, tangents)); }
public source MakeColladaPositions(string name) { EnsureDeduplicationMap(); int index = 0; var positions = new float[Deduplicator.Vertices.Uniques.Count * 3]; foreach (var vertex in Deduplicator.Vertices.Uniques) { var pos = vertex.Position; positions[index++] = pos[0]; positions[index++] = pos[1]; positions[index++] = pos[2]; } return(ColladaUtils.MakeFloatSource(name, "positions", new string[] { "X", "Y", "Z" }, positions)); }
public source MakeColladaBinormals(string name) { EnsureDeduplicationMap(); int index = 0; var binormals = new float[Deduplicator.DeduplicatedPositions.Count * 3]; foreach (var vertex in Deduplicator.DeduplicatedPositions) { var binormal = vertex.Binormal; binormals[index++] = binormal[0]; binormals[index++] = binormal[1]; binormals[index++] = binormal[2]; } return(ColladaUtils.MakeFloatSource(name, "binormals", new string[] { "X", "Y", "Z" }, binormals)); }
public source MakeColladaTangents(string name) { EnsureDeduplicationMap(); int index = 0; var tangents = new float[Deduplicator.DeduplicatedPositions.Count * 3]; foreach (var vertex in Deduplicator.DeduplicatedPositions) { var tangent = vertex.Tangent; tangents[index++] = tangent[0]; tangents[index++] = tangent[1]; tangents[index++] = tangent[2]; } return(ColladaUtils.MakeFloatSource(name, "tangents", new string[] { "X", "Y", "Z" }, tangents)); }
public source MakeBoneWeights(string name) { EnsureDeduplicationMap(); var weights = new List <float>(Deduplicator.Vertices.Uniques.Count); foreach (var vertex in Deduplicator.Vertices.Uniques) { var boneWeights = vertex.Weights; for (int i = 0; i < 4; i++) { if (boneWeights[i] > 0) { weights.Add(boneWeights[i] / 255.0f); } } } return(ColladaUtils.MakeFloatSource(name, "weights", new string[] { "WEIGHT" }, weights.ToArray())); }
public source MakeColladaUVs(string name, int uvIndex, bool flip) { EnsureDeduplicationMap(); int index = 0; var uvs = new float[Deduplicator.UVs[uvIndex].Uniques.Count * 2]; foreach (var uv in Deduplicator.UVs[uvIndex].Uniques) { uvs[index++] = uv[0]; if (flip) { uvs[index++] = 1.0f - uv[1]; } else { uvs[index++] = uv[1]; } } return(ColladaUtils.MakeFloatSource(name, "uvs" + uvIndex.ToString(), new string[] { "S", "T" }, uvs)); }
public skin ExportSkin(List <Bone> bones, Dictionary <string, Bone> nameMaps, string geometryId) { var sources = new List <source>(); var joints = new List <string>(); var poses = new List <float>(); var boundBones = new HashSet <string>(); var orderedBones = new List <Bone>(); foreach (var boneBinding in BoneBindings) { boundBones.Add(boneBinding.BoneName); orderedBones.Add(nameMaps[boneBinding.BoneName]); } /* * Append all bones to the end of the bone list, even if they're not influencing the mesh. * We need this because some tools (eg. Blender) expect all bones to be present, otherwise their * inverse world transform would reset to identity. */ foreach (var bone in bones) { if (!boundBones.Contains(bone.Name)) { orderedBones.Add(bone); } } foreach (var bone in orderedBones) { boundBones.Add(bone.Name); joints.Add(bone.Name); var invWorldTransform = FloatsToMatrix(bone.InverseWorldTransform); invWorldTransform.Transpose(); poses.AddRange(new float[] { invWorldTransform.M11, invWorldTransform.M12, invWorldTransform.M13, invWorldTransform.M14, invWorldTransform.M21, invWorldTransform.M22, invWorldTransform.M23, invWorldTransform.M24, invWorldTransform.M31, invWorldTransform.M32, invWorldTransform.M33, invWorldTransform.M34, invWorldTransform.M41, invWorldTransform.M42, invWorldTransform.M43, invWorldTransform.M44 }); } var jointSource = ColladaUtils.MakeNameSource(Name, "joints", new string[] { "JOINT" }, joints.ToArray()); var poseSource = ColladaUtils.MakeFloatSource(Name, "poses", new string[] { "TRANSFORM" }, poses.ToArray(), 16, "float4x4"); var weightsSource = PrimaryVertexData.MakeBoneWeights(Name); var vertices = PrimaryVertexData.Deduplicator.DeduplicatedPositions; var vertexInfluenceCounts = new List <int>(vertices.Count); var vertexInfluences = new List <int>(vertices.Count); int weightIdx = 0; foreach (var vertex in vertices) { int influences = 0; var indices = vertex.BoneIndices; var weights = vertex.BoneWeights; for (int i = 0; i < 4; i++) { if (weights[i] > 0) { influences++; vertexInfluences.Add(indices[i]); vertexInfluences.Add(weightIdx++); } } vertexInfluenceCounts.Add(influences); } var jointOffsets = new InputLocalOffset(); jointOffsets.semantic = "JOINT"; jointOffsets.source = "#" + jointSource.id; jointOffsets.offset = 0; var weightOffsets = new InputLocalOffset(); weightOffsets.semantic = "WEIGHT"; weightOffsets.source = "#" + weightsSource.id; weightOffsets.offset = 1; var vertWeights = new skinVertex_weights(); vertWeights.count = (ulong)vertices.Count; vertWeights.input = new InputLocalOffset[] { jointOffsets, weightOffsets }; vertWeights.v = string.Join(" ", vertexInfluences.Select(x => x.ToString()).ToArray()); vertWeights.vcount = string.Join(" ", vertexInfluenceCounts.Select(x => x.ToString()).ToArray()); var skin = new skin(); skin.source1 = "#" + geometryId; skin.bind_shape_matrix = "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"; var skinJoints = new skinJoints(); var skinJointInput = new InputLocal(); skinJointInput.semantic = "JOINT"; skinJointInput.source = "#" + jointSource.id; var skinInvBindInput = new InputLocal(); skinInvBindInput.semantic = "INV_BIND_MATRIX"; skinInvBindInput.source = "#" + poseSource.id; skinJoints.input = new InputLocal[] { skinJointInput, skinInvBindInput }; skin.joints = skinJoints; skin.source = new source[] { jointSource, poseSource, weightsSource }; skin.vertex_weights = vertWeights; return(skin); }
public List <animation> ExportKeyframeTrack(TransformTrack transformTrack, string name, string target) { var track = transformTrack.ToKeyframes(); track.MergeAdjacentFrames(); track.InterpolateFrames(); var anims = new List <animation>(); var inputs = new List <InputLocal>(); var outputs = new List <float>(track.Keyframes.Count * 16); foreach (var keyframe in track.Keyframes.Values) { var transform = keyframe.ToTransform().ToMatrix4(); transform.Transpose(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(track.Keyframes.Count); for (int i = 0; i < track.Keyframes.Count; i++) { interpolations.Add("LINEAR"); } var knots = new List <float>(track.Keyframes.Count); foreach (var keyframe in track.Keyframes) { knots.Add(keyframe.Key); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (track.Keyframes.Count == 1) { knots.Add(transformTrack.ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "INTERPOLATION" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); return(anims); }
public List <animation> ExportTransform(IList <Keyframe> keyframes, string name, string target) { var anims = new List <animation>(); var inputs = new List <InputLocal>(); var outputs = new List <float>(keyframes.Count * 16); foreach (var keyframe in keyframes) { var transform = Matrix4.Identity; if (keyframe.hasRotation) { transform *= Matrix4.CreateFromQuaternion(keyframe.rotation.Inverted()); } if (keyframe.hasScaleShear) { var scaleShear = Matrix4.Identity; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { scaleShear[i, j] = keyframe.scaleShear[i, j]; } } transform *= scaleShear; } if (keyframe.hasTranslation) { transform[0, 3] += keyframe.translation[0]; transform[1, 3] += keyframe.translation[1]; transform[2, 3] += keyframe.translation[2]; } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(keyframes.Count); for (int i = 0; i < keyframes.Count; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } var knots = new List <float>(keyframes.Count); foreach (var keyframe in keyframes) { knots.Add(keyframe.time); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (keyframes.Count == 1) { knots.Add(ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "INTERPOLATION" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); return(anims); }
public List <animation> ExportTransform(string name, string target) { var anims = new List <animation>(); if (NumKnots() > 0) { var inputs = new List <InputLocal>(); var numKnots = NumKnots(); var knots = GetKnots(); var outputs = new List <float>(knots.Count * 16); var quats = GetQuaternions(); foreach (var rotation in quats) { var transform = Matrix4.CreateFromQuaternion(rotation); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { outputs.Add(transform[i, j]); } } } var interpolations = new List <string>(numKnots); for (int i = 0; i < numKnots; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (numKnots == 1) { knots.Add(ParentAnimation.Duration); for (int i = 0; i < 16; i++) { outputs.Add(outputs[i]); } interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); anims.Add(animation); } return(anims); }
public animation ExportChannel(string name, string target, string paramName, int coordinate, bool isRotation) { var inputs = new List <InputLocal>(); var numKnots = NumKnots(); var knots = GetKnots(); var outputs = ExportChannelControlData(coordinate, isRotation); var interpolations = new List <string>(numKnots); for (int i = 0; i < numKnots; i++) { // TODO: Add control point estimation code and add in/out tangents for Bezier //interpolations.Add("BEZIER"); interpolations.Add("LINEAR"); } /* * Fix up animations that have only one keyframe by adding another keyframe at * the end of the animation. * (This mainly applies to DaIdentity and DnConstant32f) */ if (numKnots == 1) { knots.Add(ParentAnimation.Duration); outputs.Add(outputs[0]); interpolations.Add(interpolations[0]); } var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); var knotsInput = new InputLocal(); knotsInput.semantic = "INPUT"; knotsInput.source = "#" + knotsSource.id; inputs.Add(knotsInput); var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { paramName }, outputs.ToArray()); var outInput = new InputLocal(); outInput.semantic = "OUTPUT"; outInput.source = "#" + outSource.id; inputs.Add(outInput); var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "" }, interpolations.ToArray()); var interpInput = new InputLocal(); interpInput.semantic = "INTERPOLATION"; interpInput.source = "#" + interpSource.id; inputs.Add(interpInput); var sampler = new sampler(); sampler.id = name + "_sampler"; sampler.input = inputs.ToArray(); var channel = new channel(); channel.source = "#" + sampler.id; channel.target = target; var animation = new animation(); animation.id = name; animation.name = name; var animItems = new List <object>(); animItems.Add(knotsSource); animItems.Add(outSource); animItems.Add(interpSource); animItems.Add(sampler); animItems.Add(channel); animation.Items = animItems.ToArray(); return(animation); }