Пример #1
0
        private void AddInput(source collSource, string inputSemantic, string localInputSemantic = null, ulong setIndex = 0)
        {
            if (collSource != null)
            {
                Sources.Add(collSource);
            }

            if (inputSemantic != null)
            {
                var input = new InputLocal();
                input.semantic = inputSemantic;
                input.source   = "#" + collSource.id;
                Inputs.Add(input);
            }

            if (localInputSemantic != null)
            {
                var vertexInputOff = new InputLocalOffset();
                vertexInputOff.semantic = localInputSemantic;
                vertexInputOff.source   = "#" + collSource.id;
                vertexInputOff.offset   = LastInputOffset++;
                if (localInputSemantic == "TEXCOORD" || localInputSemantic == "COLOR")
                {
                    vertexInputOff.set = setIndex;
                }

                InputOffsets.Add(vertexInputOff);
            }
        }
Пример #2
0
        public static InputLocalOffset makeInputOffset(string source, string semantic,
                                                       ulong offset, bool setSpecified, ulong set)
        {
            InputLocalOffset input = new InputLocalOffset();

            input.source       = "#" + source;
            input.semantic     = semantic;
            input.offset       = offset;
            input.set          = set;
            input.setSpecified = setSpecified;
            return(input);
        }
Пример #3
0
        public static source FindSourceFromInput(InputLocalOffset input, source[] sources)
        {
            string inputSource = input.source.Trim('#');

            if (sources.Any(x => x.id == inputSource))
            {
                return(Array.Find(sources, x => x.id == inputSource));
            }
            else
            {
                return(null);
            }
        }
Пример #4
0
 private void SetVertices(InputLocalOffset input, int[] p, int stepSize, Dictionary <string, MeshSource> sources, DAEVertexDescription[] outputVertices)
 {
     if (input.semantic.Equals("VERTEX"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].Vertex = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("NORMAL"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].Normal = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("TEXCOORD"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexCoord = meshSource.GetVector3(idx);
             outputVertices[i].TexCoord = new DAEVector3(outputVertices[i].TexCoord.X, 1 - outputVertices[i].TexCoord.Y, outputVertices[i].TexCoord.Z);
         }
     }
     else if (input.semantic.Equals("TEXTANGENT"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexTangent = meshSource.GetVector3(idx);
         }
     }
     else if (input.semantic.Equals("TEXBINORMAL"))
     {
         MeshSource meshSource = sources[DAEUtils.GetUrl(input.source).Id];
         for (int i = 0; i < outputVertices.Length; i++)
         {
             int idx = p[i * stepSize + (int)input.offset];
             outputVertices[i].TexBinormal = meshSource.GetVector3(idx);
         }
     }
 }
Пример #5
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);
        }
Пример #6
0
        public mesh ExportToCollada(ExporterOptions options)
        {
            // TODO: model transform/inverse transform?

            source vertexSource = null;
            var    sources      = new List <source>();
            ulong  inputOffset  = 0;
            var    inputs       = new List <InputLocal>();
            var    inputOffsets = new List <InputLocalOffset>();

            foreach (var component in PrimaryVertexData.VertexComponentNames)
            {
                var    input  = new InputLocal();
                source source = null;
                switch (component.String)
                {
                case "Position":
                {
                    source         = PrimaryVertexData.MakeColladaPositions(Name);
                    vertexSource   = source;
                    input.semantic = "POSITION";

                    var vertexInputOff = new InputLocalOffset();
                    vertexInputOff.semantic = "VERTEX";
                    vertexInputOff.source   = "#" + source.id;
                    vertexInputOff.offset   = inputOffset++;
                    inputOffsets.Add(vertexInputOff);
                    break;
                }

                case "Normal":
                {
                    if (options.ExportNormals)
                    {
                        source         = PrimaryVertexData.MakeColladaNormals(Name);
                        input.semantic = "NORMAL";
                    }
                    break;
                }

                case "Tangent":
                {
                    if (options.ExportTangents)
                    {
                        source         = PrimaryVertexData.MakeColladaTangents(Name);
                        input.semantic = "TANGENT";
                    }
                    break;
                }

                case "Binormal":
                {
                    if (options.ExportTangents)
                    {
                        source         = PrimaryVertexData.MakeColladaBinormals(Name);
                        input.semantic = "BINORMAL";
                    }
                    break;
                }

                case "MaxChannel_1":
                case "MaxChannel_2":
                case "UVChannel_1":
                case "UVChannel_2":
                {
                    if (options.ExportUVs)
                    {
                        int uvIndex = Int32.Parse(component.String.Substring(11)) - 1;
                        source = PrimaryVertexData.MakeColladaUVs(Name, uvIndex);

                        var texInputOff = new InputLocalOffset();
                        texInputOff.semantic = "TEXCOORD";
                        texInputOff.source   = "#" + source.id;
                        texInputOff.offset   = inputOffset++;
                        inputOffsets.Add(texInputOff);
                    }
                    break;
                }

                case "BoneWeights":
                case "BoneIndices":
                    // These are handled in ExportSkin()
                    break;

                case "DiffuseColor0":
                case "map1":     // Possibly bogus D:OS name for DiffuseColor0
                    // TODO: This is not exported at the moment.
                    break;

                default:
                    throw new NotImplementedException("Vertex component not supported: " + component.String);
                }

                if (source != null)
                {
                    sources.Add(source);
                }

                if (input.semantic != null)
                {
                    input.source = "#" + source.id;
                    inputs.Add(input);
                }
            }

            var triangles = PrimaryTopology.MakeColladaTriangles(
                inputOffsets.ToArray(),
                PrimaryVertexData.Deduplicator.VertexDeduplicationMap,
                PrimaryVertexData.Deduplicator.UVDeduplicationMaps
                );

            var colladaMesh = new mesh();

            colladaMesh.vertices       = new vertices();
            colladaMesh.vertices.id    = Name + "-vertices";
            colladaMesh.vertices.input = inputs.ToArray();
            colladaMesh.source         = sources.ToArray();
            colladaMesh.Items          = new object[] { triangles };

            return(colladaMesh);
        }