Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
        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));
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
        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));
        }
Example #7
0
        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));
        }
Example #8
0
        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()));
        }
Example #9
0
        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));
        }
Example #10
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }
Example #14
0
        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);
        }