Пример #1
0
            public XnaBoneWeightChannel(MeshBuilder mb, VertexContainer vc, JointList joints)
                : base(mb)
            {
                try
                {
                    _indicesChannel = (from c in vc.VertexChannels
                                       where c.Contains(VertexElementUsage.BlendIndices)
                                       select c).First();

                    _weightChannel = (from c in vc.VertexChannels
                                      where c.Contains(VertexElementUsage.BlendWeight)
                                      select c).First();
                }
                catch (Exception)
                {
                    throw new Exception("Missing blend indices or weights");
                }

                _joints        = joints;
                _vertexSize    = vc.VertexSize;
                _indicesOffset = _indicesChannel.Source.Offset;
                _weightOffset  = _weightChannel.Source.Offset;

                this.Create();
            }
Пример #2
0
            /// <summary>
            /// Creates a new vertex channel using the given MeshBuilder based on a
            /// Collada VertexChannel. No data is initially added to the vertex channel!
            /// For this, use the SetData method.
            /// </summary>
            /// <param name="meshBuilder">MeshBuilder instance to store vertex channel in</param>
            /// <param name="colladaVertexChannel">Original COLLADA Vertex Channel</param>
            public XnaVertexChannel(MeshBuilder meshBuilder, CVertexChannel colladaVertexChannel)
            {
                _colladaVertexChannel = colladaVertexChannel;
                _meshBuilder          = meshBuilder;
                _vertexSize           = colladaVertexChannel.Source.Stride;
                _offset = colladaVertexChannel.Source.Offset;

                Create();
            }
Пример #3
0
        /// <summary>
        /// Creates MeshContent instances for each mesh in the COLLADA model and attaches
        /// them to the NodeContent root.
        /// </summary>
        void CreateMeshes()
        {
            foreach (Mesh mesh in collada.Meshes)
            {
                foreach (MeshPart part in mesh.MeshParts)
                {
                    var material = materials[part.MaterialName];
                    meshBuilder = MeshBuilder.StartMesh(mesh.Name);
                    meshBuilder.SwapWindingOrder        = false;
                    meshBuilder.MergeDuplicatePositions = false;
                    meshBuilder.SetMaterial(material);
                    meshBuilder.Name = mesh.Name;

                    // Positions
                    CVertexChannel posChannel = part.Vertices.VertexChannels.Where(c =>
                                                                                   c.Description.VertexElementUsage == VertexElementUsage.Position).
                                                FirstOrDefault();

                    VertexContainer container = part.Vertices;
                    float[]         data      = container.Vertices;
                    int             posOffset = posChannel.Source.Offset;

                    for (int i = 0; i < container.Vertices.Length; i += container.VertexSize)
                    {
                        Vector3 pos = new Vector3(data[i + posOffset + 0],
                                                  data[i + posOffset + 1], data[i + posOffset + 2]);
                        meshBuilder.CreatePosition(pos);
                    }

                    // Vertex channels other than position
                    List <XnaVertexChannel> channels = new List <XnaVertexChannel>();

                    foreach (CVertexChannel cvChannel in part.Vertices.VertexChannels)
                    {
                        switch (cvChannel.Description.VertexElementUsage)
                        {
                        case VertexElementUsage.Position:
                            // Position is already created above
                            break;

                        case VertexElementUsage.BlendWeight:
                        case VertexElementUsage.BlendIndices:
                            // When bone weight collections are used these two
                            // channels get added separately later
                            if (UseBoneWeightCollection || excludeBlendWeights)
                            {
                                break;
                            }
                            else
                            {
                                goto default;
                            }

                        default:
                            // standard channel like texcoord, normal etc.
                            channels.Add(new XnaVertexChannel(meshBuilder, cvChannel));
                            break;
                        }
                    }

                    // BoneWeightCollection vertex channel
                    if (UseBoneWeightCollection && !excludeBlendWeights)
                    {
                        try
                        {
                            channels.Add(new XnaBoneWeightChannel(meshBuilder, part.Vertices,
                                                                  collada.Joints));
                        }
                        catch (Exception)
                        {
                            importerContext.Logger.LogMessage("No skinning information found");
                        }
                    }

                    // Triangles
                    for (int i = 0; i < part.Indices.Length; i += 3)
                    {
                        for (int j = i; j < i + 3; j++)
                        {
                            // Set channel components (other than position)
                            foreach (var channel in channels)
                            {
                                channel.SetData(j);
                            }

                            meshBuilder.AddTriangleVertex(part.Indices[j]);
                        }
                    }

                    MeshContent meshContent = meshBuilder.FinishMesh();

                    if (material.OpaqueData.Count > 0)
                    {
                        // Copy opaque data from material to mesh for convenience and
                        // to make it compatible to Normal Mapping sample from App Hub
                        foreach (var pair in material.OpaqueData)
                        {
                            meshContent.OpaqueData.Add(pair.Key, pair.Value);
                        }
                    }
                    else
                    {
                        importerContext.Logger.LogWarning(null, null, "No opaque data in mesh");
                    }

                    rootNode.Children.Add(meshContent);
                }
            }
        }