Esempio n. 1
0
 public static Skeleton FromCollada(node root)
 {
     var skeleton = new Skeleton();
     skeleton.Bones = new List<Bone>();
     skeleton.LODType = 0;
     skeleton.Name = root.name;
     skeleton.BonesBySID = new Dictionary<string, Bone>();
     skeleton.BonesByID = new Dictionary<string, Bone>();
     Bone.FromCollada(root, -1, skeleton.Bones, skeleton.BonesBySID, skeleton.BonesByID);
     return skeleton;
 }
Esempio n. 2
0
        private void ConformSkeleton(Skeleton skeleton, Skeleton conformToSkeleton)
        {
            skeleton.LODType = conformToSkeleton.LODType;

            // TODO: Tolerate missing bones?
            foreach (var conformBone in conformToSkeleton.Bones)
            {
                Bone inputBone = null;
                foreach (var bone in skeleton.Bones)
                {
                    if (bone.Name == conformBone.Name)
                    {
                        inputBone = bone;
                        break;
                    }
                }

                if (inputBone == null)
                {
                    string msg = String.Format(
                        "No matching bone found for conforming bone '{1}' in skeleton '{0}'.",
                        skeleton.Name, conformBone.Name
                    );
                    throw new ExportException(msg);
                }

                // Bones must have the same parent. We check this in two steps:
                // 1) Either both of them are root bones (no parent index) or none of them are.
                if ((conformBone.ParentIndex == -1) != (inputBone.ParentIndex == -1))
                {
                    string msg = String.Format(
                        "Cannot map non-root bones to root bone '{1}' for skeleton '{0}'.",
                        skeleton.Name, conformBone.Name
                    );
                    throw new ExportException(msg);
                }

                // 2) The name of their parent bones is the same (index may differ!)
                if (conformBone.ParentIndex != -1)
                {
                    var conformParent = conformToSkeleton.Bones[conformBone.ParentIndex];
                    var inputParent = skeleton.Bones[inputBone.ParentIndex];
                    if (conformParent.Name != inputParent.Name)
                    {
                        string msg = String.Format(
                            "Conforming parent ({1}) for bone '{2}' differs from input parent ({3}) for skeleton '{0}'.",
                            skeleton.Name, conformParent.Name, conformBone.Name, inputParent.Name
                        );
                        throw new ExportException(msg);
                    }
                }
                

                // The bones match, copy relevant parameters from the conforming skeleton to the input.
                inputBone.InverseWorldTransform = conformBone.InverseWorldTransform;
                inputBone.LODError = conformBone.LODError;
                inputBone.Transform = conformBone.Transform;
            }
        }
Esempio n. 3
0
        public bool ImportFromCollada(animation colladaAnim, Skeleton skeleton)
        {
            Animation = colladaAnim;
            ImportSources();
            ImportSampler();

            // Avoid importing empty animations
            if (Transforms.Count == 0)
                return false;

            ImportChannel(skeleton);
            return true;
        }
Esempio n. 4
0
        private void GenerateDummySkeleton(Root root)
        {
            foreach (var model in root.Models)
            {
                if (model.Skeleton == null)
                {
                    Utils.Info(String.Format("Generating dummy skeleton for model '{0}'", model.Name));
                    var skeleton = new Skeleton();
                    skeleton.Name = model.Name;
                    skeleton.LODType = 0;
                    skeleton.IsDummy = true;
                    root.Skeletons.Add(skeleton);

                    var bone = new Bone();
                    bone.Name = model.Name;
                    bone.ParentIndex = -1;
                    skeleton.Bones = new List<Bone> { bone };
                    bone.Transform = new Transform();

                    // TODO: Transform / IWT is not always identity on dummy bones!
                    skeleton.UpdateInverseWorldTransforms();
                    model.Skeleton = skeleton;

                    foreach (var mesh in model.MeshBindings)
                    {
                        if (mesh.Mesh.BoneBindings != null && mesh.Mesh.BoneBindings.Count > 0)
                        {
                            throw new ParsingException("Failed to generate dummy skeleton: Mesh already has bone bindings.");
                        }

                        var binding = new BoneBinding();
                        binding.BoneName = bone.Name;
                        // TODO: Calculate bounding box!
                        binding.OBBMin = new float[] { -10, -10, -10 };
                        binding.OBBMax = new float[] { 10, 10, 10 };
                        mesh.Mesh.BoneBindings = new List<BoneBinding> { binding };
                    }
                }
            }
        }
Esempio n. 5
0
        private void ImportChannel(Skeleton skeleton)
        {
            channel channel = null;
            foreach (var item in Animation.Items)
            {
                if (item is channel)
                {
                    channel = item as channel;
                    break;
                }
            }

            if (channel == null)
                throw new ParsingException("Animation " + Animation.id + " has no channel!");

            var parts = channel.target.Split(new char[] { '/' });
            if (parts.Length != 2)
                throw new ParsingException("Unsupported channel target format: " + channel.target);

            Bone bone = null;
            if (!skeleton.BonesByID.TryGetValue(parts[0], out bone))
                throw new ParsingException("Animation channel references nonexistent bone: " + parts[0]);

            if (bone.TransformSID != parts[1])
                throw new ParsingException("Animation channel references nonexistent transform or transform is not float4x4: " + channel.target);

            Bone = bone;
        }