示例#1
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Mesh assimpMesh)
        {
            var meshPart = new ModelData.MeshPart
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                VertexBufferRange = new ModelData.BufferRange {
                    Slot = mesh.VertexBuffers.Count
                },
                IndexBufferRange = new ModelData.BufferRange {
                    Slot = mesh.IndexBuffers.Count
                }
            };

            var vertexBuffer = new ModelData.VertexBuffer
            {
                Layout = new List <VertexElement>()
            };

            mesh.VertexBuffers.Add(vertexBuffer);

            var indexBuffer = new ModelData.IndexBuffer();

            mesh.IndexBuffers.Add(indexBuffer);

            var layout = vertexBuffer.Layout;

            int vertexBufferElementSize = 0;

            // Add position
            layout.Add(VertexElement.PositionTransformed(Format.R32G32B32_Float, 0));
            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();

            // Add normals
            if (assimpMesh.HasNormals)
            {
                layout.Add(VertexElement.Normal(0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
            }

            // Add colors
            if (assimpMesh.VertexColorChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++)
                {
                    if (assimpMesh.HasVertexColors(i))
                    {
                        layout.Add(VertexElement.Normal(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += SharpDX.Utilities.SizeOf <Color4>();
                        localIndex++;
                    }
                }
            }

            // Add textures
            if (assimpMesh.TextureCoordsChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.TextureCoordsChannelCount; i++)
                {
                    if (assimpMesh.HasTextureCoords(i))
                    {
                        var uvCount = assimpMesh.GetUVComponentCount(i);

                        if (uvCount == 2)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected uv count");
                        }

                        localIndex++;
                    }
                }
            }

            if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates))
            {
                layout.Add(new VertexElement("BARYCENTRIC", 0, Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
            }
            else
            // Add tangent / bitangent
            if (assimpMesh.HasTangentBasis)
            {
                if (!options.ExcludeElements.Contains("Tangent"))
                {
                    layout.Add(VertexElement.Tangent(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector4>();
                }

                if (!options.ExcludeElements.Contains("BiTangent"))
                {
                    layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += SharpDX.Utilities.SizeOf <Vector3>();
                }
            }

            if (options.ModelOperations.HasFlag(ModelOperation.CalculateBarycentricCoordinates))
            {
                WriteBarycentricVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize);
            }
            else
            {
                WriteVertices(assimpMesh, meshPart, vertexBuffer, vertexBufferElementSize);
            }
            WriteIndices(assimpMesh, meshPart, indexBuffer);
            return(meshPart);
        }
示例#2
0
        private void CollectNodes(Node node)
        {
            bool isModelNode = IsModelNode(node);

            if (!isModelNode)
            {
                return;
            }

            // if node has meshes, create a new scene object for it
            if (node.MeshCount > 0)
            {
                var mesh = new ModelData.Mesh
                {
                    Name      = node.Name,
                    MeshParts = new List <ModelData.MeshPart>()
                };
                model.Meshes.Add(mesh);

                // Precalculate the number of vertices for bounding sphere calculation
                boundingPointCount = 0;
                for (int i = 0; i < node.MeshCount; i++)
                {
                    var meshIndex = node.MeshIndices[i];
                    var meshPart  = scene.Meshes[meshIndex];
                    boundingPointCount += meshPart.VertexCount;
                }

                // Reallocate the buffer if needed
                if (boundingPoints == null || boundingPoints.Length < boundingPointCount)
                {
                    boundingPoints = new Vector3[boundingPointCount];
                }

                currentBoundingPointIndex = 0;
                for (int i = 0; i < node.MeshCount; i++)
                {
                    var meshIndex = node.MeshIndices[i];
                    var meshPart  = Process(mesh, scene.Meshes[meshIndex]);

                    var meshToPartList = registeredMeshParts[meshIndex];
                    if (meshToPartList == null)
                    {
                        meshToPartList = new List <ModelData.MeshPart>();
                        registeredMeshParts[meshIndex] = meshToPartList;
                    }

                    meshToPartList.Add(meshPart);
                    mesh.MeshParts.Add(meshPart);
                }

                // Calculate the bounding sphere.
                BoundingSphere.FromPoints(boundingPoints, 0, boundingPointCount, out mesh.BoundingSphere);
            }

            // continue for all child nodes
            if (node.HasChildren)
            {
                foreach (var subNode in node.Children)
                {
                    CollectNodes(subNode);
                }
            }
        }