Пример #1
0
        void TestMesh(Assimp.Mesh netMesh, AssimpSharp.Mesh sharpMesh)
        {
            // Vertices
            Assert.AreEqual(netMesh.HasVertices, sharpMesh.Vertices != null);
            if (netMesh.HasVertices)
            {
                Assert.AreEqual(netMesh.VertexCount, sharpMesh.Vertices.Length);
                MathAssert.AreEqual(netMesh.Vertices, sharpMesh.Vertices);
            }
            // Faces
            Assert.AreEqual(netMesh.HasFaces, sharpMesh.Faces != null);
            if (netMesh.HasFaces)
            {
                Assert.AreEqual(netMesh.FaceCount, sharpMesh.Faces.Length);
                for (int i = 0; i < netMesh.FaceCount; i++)
                {
                    Assert.AreEqual(netMesh.Faces[i].HasIndices, sharpMesh.Faces[i].Indices != null);
                    Assert.AreEqual(netMesh.Faces[i].IndexCount, sharpMesh.Faces[i].Indices.Length);
                    Assert.AreEqual(netMesh.Faces[i].Indices, sharpMesh.Faces[i].Indices);
                }
            }
            // Normals
            Assert.AreEqual(netMesh.HasNormals, sharpMesh.Normals != null);
            if (netMesh.HasNormals)
            {
                MathAssert.AreEqual(netMesh.Normals, sharpMesh.Normals);
            }

            // BiTangents
            Assert.AreEqual(netMesh.HasTangentBasis, sharpMesh.Bitangents != null && sharpMesh.Bitangents.Length > 0);
            if (netMesh.HasTangentBasis)
            {
                MathAssert.AreEqual(netMesh.BiTangents, sharpMesh.Bitangents);
            }
            // PrimitiveType
            // AssimpNet BUG!!
            //Assert.AreEqual(netMesh.PrimitiveType.ToString(), Enum.GetName(typeof(AssimpSharp.PrimitiveType), sharpMesh.PrimitiveTypes));
            // TexureCoord
            for (int i = 0; i < netMesh.TextureCoordinateChannelCount; i++)
            {
                Assert.AreEqual(netMesh.HasTextureCoords(i), sharpMesh.HasTextureCoords(i));
                MathAssert.AreEqual(netMesh.TextureCoordinateChannels[i], sharpMesh.TextureCoords[i]);
            }
            // VertexColorChannels
            for (int i = 0; i < netMesh.VertexColorChannelCount; i++)
            {
                Assert.AreEqual(netMesh.HasVertexColors(i), sharpMesh.HasVertexColors(i));
                if (netMesh.HasVertexColors(i))
                {
                    Assert.AreEqual(netMesh.VertexColorChannels[i], sharpMesh.Colors[i]);
                }
            }
            // MaterialIndex
            Assert.AreEqual(netMesh.MaterialIndex, sharpMesh.MaterialIndex);
            // Name
            Assert.AreEqual(netMesh.Name, sharpMesh.Name);
            // UVComponentCount
            Assert.AreEqual(netMesh.UVComponentCount, sharpMesh.NumUVComponents);
            // MeshAnimationAttachments
            Assert.AreEqual(netMesh.HasMeshAnimationAttachments, sharpMesh.AnimMeshes != null);
            if (netMesh.HasMeshAnimationAttachments)
            {
                for (int i = 0; i < netMesh.MeshAnimationAttachmentCount; i++)
                {
                    TestAnimationAttachment(netMesh.MeshAnimationAttachments[i], sharpMesh.AnimMeshes[i]);
                }
            }
        }
Пример #2
0
 void TestAnimationAttachment(Assimp.MeshAnimationAttachment netAnimMesh, AssimpSharp.AnimMesh sharpAnimMesh)
 {
     Assert.AreEqual(netAnimMesh.HasVertices, sharpAnimMesh.HasPosition);
     if (netAnimMesh.HasVertices)
     {
         Assert.AreEqual(netAnimMesh.Vertices, sharpAnimMesh.Vertices);
     }
     Assert.AreEqual(netAnimMesh.HasNormals, sharpAnimMesh.HasNormals);
     if (netAnimMesh.HasNormals)
     {
         Assert.AreEqual(netAnimMesh.Normals, sharpAnimMesh.Normals);
     }
     Assert.AreEqual(netAnimMesh.HasTangentBasis, sharpAnimMesh.HasTangentsAndBitangets);
     if (netAnimMesh.HasTangentBasis)
     {
         Assert.AreEqual(netAnimMesh.Tangents, sharpAnimMesh.Tangents);
         Assert.AreEqual(netAnimMesh.BiTangents, sharpAnimMesh.Bitangents);
     }
     for (int i = 0; i < netAnimMesh.TextureCoordinateChannelCount; i++)
     {
         Assert.AreEqual(netAnimMesh.HasTextureCoords(i), sharpAnimMesh.HasTextureCoords(i));
         if (netAnimMesh.HasTextureCoords(i))
         {
             Assert.AreEqual(netAnimMesh.TextureCoordinateChannels[i], sharpAnimMesh.TextureCoords[i]);
         }
     }
     for (int i = 0; i < netAnimMesh.VertexColorChannelCount; i++)
     {
         Assert.AreEqual(netAnimMesh.HasVertexColors(i), sharpAnimMesh.HasVertexColors(i));
         if (netAnimMesh.HasVertexColors(i))
         {
             Assert.AreEqual(netAnimMesh.VertexColorChannels[i], sharpAnimMesh.Colors[i]);
         }
     }
 }
Пример #3
0
        //determine the number of elements in the vertex
        private int GetNoofInputElements(Assimp.Mesh mesh)
        {

            bool hasTexCoords = mesh.HasTextureCoords(0);
            bool hasColors = mesh.HasVertexColors(0);
            bool hasNormals = mesh.HasNormals;
            bool hasTangents = mesh.Tangents != null;
            bool hasBitangents = mesh.BiTangents != null;

            int noofElements = 1;

            if (hasColors)
                noofElements++;

            if (hasNormals)
                noofElements++;

            if (hasTangents)
                noofElements++;

            if (hasBitangents)
                noofElements++;

            if (hasTexCoords)
                noofElements++;

            return noofElements;
        }
Пример #4
0
        private ModelData.MeshPart Process(ModelData.Mesh mesh, Assimp.Mesh assimpMesh)
        {
            var meshPart = new ModelData.MeshPart()
                               {
                                   MaterialIndex = assimpMesh.MaterialIndex,
                                   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 += Utilities.SizeOf<SharpDX.Vector3>();

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

            // Add colors
            if (assimpMesh.VertexColorChannelCount > 0)
            {
                for (int localIndex = 0, i = 0; i < assimpMesh.VertexColorChannelCount; i++)
                {
                    if (assimpMesh.HasVertexColors(i))
                    {
                        layout.Add(VertexElement.Color(localIndex, Format.R32G32B32A32_Float, vertexBufferElementSize));
                        vertexBufferElementSize += Utilities.SizeOf<SharpDX.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 += Utilities.SizeOf<SharpDX.Vector2>();
                        }
                        else if (uvCount == 3)
                        {
                            layout.Add(VertexElement.TextureCoordinate(localIndex, Format.R32G32B32_Float, vertexBufferElementSize));
                            vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();
                        }
                        else
                        {
                            throw new InvalidOperationException("Unexpected uv count");
                        }

                        localIndex++;
                    }
                }
            }

            // Add tangent / bitangent
            if (assimpMesh.HasTangentBasis)
            {
                layout.Add(VertexElement.Tangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();

                layout.Add(VertexElement.BiTangent(Format.R32G32B32_Float, vertexBufferElementSize));
                vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector3>();
            }

            // Extract Skinning Indices / Weights
            bool hasWeights = false;
            var skinningCount   = new int[assimpMesh.VertexCount];
            var skinningIndices = new Int4[assimpMesh.VertexCount];
            var skinningWeights = new Vector4[assimpMesh.VertexCount];

            if (assimpMesh.HasBones)
            {
                meshPart.BoneOffsetMatrices = new Matrix[assimpMesh.BoneCount];
                for (int i = 0; i < assimpMesh.Bones.Length; i++)
                {
                    var bone = assimpMesh.Bones[i];
                    meshPart.BoneOffsetMatrices[i] = ConvertMatrix(bone.OffsetMatrix);
                    if (bone.HasVertexWeights)
                    {
                        var boneNode = scene.RootNode.FindNode(bone.Name);
                        var boneIndex = skinnedBones[boneNode];
                        for (int j = 0; j < bone.VertexWeightCount; j++)
                        {
                            var weights = bone.VertexWeights[j];
                            var vertexSkinningCount = skinningCount[weights.VertexID];

                            skinningIndices[weights.VertexID][vertexSkinningCount] = boneIndex;

                            skinningWeights[weights.VertexID][vertexSkinningCount] = weights.Weight;

                            skinningCount[weights.VertexID] = ++vertexSkinningCount;
                        }

                        hasWeights = true;
                    }
                }

                if (hasWeights)
                {
                    layout.Add(VertexElement.BlendIndices(Format.R16G16B16A16_SInt, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf<SharpDX.Int4>();

                    layout.Add(VertexElement.BlendWeights(Format.R32G32B32A32_Float, vertexBufferElementSize));
                    vertexBufferElementSize += Utilities.SizeOf<SharpDX.Vector4>();
                }
            }

            // Write all vertices
            meshPart.VertexBufferRange.Count = assimpMesh.VertexCount;
            vertexBuffer.Count = assimpMesh.VertexCount;
            vertexBuffer.Buffer = new byte[vertexBufferElementSize * assimpMesh.VertexCount];

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (vertexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = vertexBuffer.Buffer.Length;
            }

            var vertexStream = DataStream.Create(vertexBuffer.Buffer, true, true);
            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                var position = assimpMesh.Vertices[i];
                vertexStream.Write(position);

                // Store bounding points for BoundingSphere pre-calculation
                boundingPoints[currentBoundingPointIndex++] = new Vector3(position.X, position.Y, position.Z);

                // Add normals
                if (assimpMesh.HasNormals)
                {
                    vertexStream.Write(assimpMesh.Normals[i]);
                }

                // Add colors
                if (assimpMesh.VertexColorChannelCount > 0)
                {
                    for (int j = 0; j < assimpMesh.VertexColorChannelCount; j++)
                    {
                        if (assimpMesh.HasVertexColors(j))
                        {
                            vertexStream.Write(assimpMesh.GetVertexColors(j)[i]);
                        }
                    }
                }

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

                            var uv = assimpMesh.GetTextureCoords(j)[i];

                            if (uvCount == 2)
                            {
                                vertexStream.Write(new Vector2(uv.X, uv.Y));
                            }
                            else
                            {
                                vertexStream.Write(uv);
                            }
                        }
                    }
                }

                // Add tangent / bitangent
                if (assimpMesh.HasTangentBasis)
                {
                    vertexStream.Write(assimpMesh.Tangents[i]);
                    vertexStream.Write(assimpMesh.BiTangents[i]);
                }

                // Add Skinning Indices/Weights
                if (assimpMesh.HasBones && hasWeights)
                {
                    vertexStream.Write(skinningIndices[i]);
                    vertexStream.Write(skinningWeights[i]);
                }
            }
            vertexStream.Dispose();

            // Write all indices
            var indices = assimpMesh.GetIntIndices();
            indexBuffer.Count = indices.Length;
            meshPart.IndexBufferRange.Count = indices.Length;
            if (meshPart.VertexBufferRange.Count < 65536)
            {
                // Write only short indices if count is less than the size of a short
                indexBuffer.Buffer = new byte[indices.Length * 2];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    foreach (int index in indices) indexStream.Write((ushort)index);
            }
            else
            {
                // Otherwise, use full 32-bit precision to store indices
                indexBuffer.Buffer = new byte[indices.Length * 4];
                using (var indexStream = DataStream.Create(indexBuffer.Buffer, true, true))
                    indexStream.WriteRange(indices);
            }

            // Update the MaximumBufferSizeInBytes needed to load this model
            if (indexBuffer.Buffer.Length > model.MaximumBufferSizeInBytes)
            {
                model.MaximumBufferSizeInBytes = indexBuffer.Buffer.Length;
            }

            return meshPart;
        }
Пример #5
0
        private static GeometryData GenerateGeometryDataFromAssimpMesh(Assimp.Mesh mesh)
        {
            var geometryData = new GeometryData
            {
                Vertices = new VertexPositionNormalTexture[mesh.VertexCount],
                Indices = new ushort[mesh.FaceCount * 3]
            };

            geometryData.Vertices = new VertexPositionNormalTexture[mesh.VertexCount];

            for (var i = 0; i < mesh.VertexCount; i++)
            {
                var vertex = mesh.Vertices[i];
                geometryData.Vertices[i].Position = new Vector3(vertex.X, vertex.Y, vertex.Z);

                var normal = mesh.HasNormals ? mesh.Normals[i] : new Vector3D();
                geometryData.Vertices[i].Normal = new Vector3(normal.X, normal.Y, normal.Z);

                var texcoord = mesh.HasTextureCoords(0) ? mesh.TextureCoordinateChannels[0][i] : new Vector3D();
                geometryData.Vertices[i].TextureCoordinate = new Vector2(texcoord.X, texcoord.Y);
            }

            for (var i = 0; i < mesh.FaceCount; i++)
            {
                geometryData.Indices[i * 3 + 0] = (ushort)mesh.Faces[i].Indices[0];
                geometryData.Indices[i * 3 + 1] = (ushort)mesh.Faces[i].Indices[1];
                geometryData.Indices[i * 3 + 2] = (ushort)mesh.Faces[i].Indices[2];
            }

            return geometryData;
        }
Пример #6
0
        public Hatzap.Models.Mesh FromAssimp(Assimp.Mesh amesh)
        {
            var mesh = new Hatzap.Models.Mesh();

            var v = amesh.Vertices;
            var n = amesh.Normals;
            var t = amesh.Tangents;
            var b = amesh.BiTangents;
            var tc = amesh.TextureCoordinateChannels;
            var c = amesh.VertexColorChannels;

            var verts = new Vector3[v.Count];
            Vector3[] norms;
            Vector3[] tangents;
            Vector3[] binormals;
            Vector3[][] uv;
            Vector4[][] colors;

            if (amesh.HasNormals) norms = new Vector3[v.Count]; else norms = null;
            if (amesh.HasTangentBasis) tangents = new Vector3[v.Count]; else tangents = null;
            if (amesh.HasTangentBasis) binormals = new Vector3[v.Count]; else binormals = null;
            if (amesh.HasTextureCoords(0))
            {
                uv = new Vector3[amesh.TextureCoordinateChannelCount][];

                for(int i = 0; i < amesh.TextureCoordinateChannelCount; i++)
                {
                    uv[i] = new Vector3[v.Count];
                }

            }
            else
            {
                uv = null;
            }
            if (amesh.HasVertexColors(0))
            {
                colors = new Vector4[amesh.VertexColorChannelCount][];

                for (int i = 0; i < amesh.VertexColorChannelCount; i++)
                {
                    colors[i] = new Vector4[v.Count];
                }
            }
            else
            {
                colors = new Vector4[1][];
                colors[0] = new Vector4[v.Count];
            }

            for (int i = 0; i < v.Count; i++)
            {
                verts[i] = new Vector3(v[i].X, v[i].Y, v[i].Z);
                if (norms != null) norms[i] = new Vector3(n[i].X, n[i].Y, n[i].Z);
                if (tangents != null) tangents[i] = new Vector3(t[i].X, t[i].Y, t[i].Z);
                if (binormals != null) binormals[i] = new Vector3(b[i].X, b[i].Y, b[i].Z);
                if (uv != null)
                {
                    for(int j = 0; j < amesh.TextureCoordinateChannelCount; j++)
                    {
                        uv[j][i] = new Vector3(tc[j][i].X, tc[j][i].Y, tc[j][i].Z);
                    }
                }
                if (colors != null)
                {
                    if (amesh.HasVertexColors(0))
                    {
                        for (int j = 0; j < amesh.VertexColorChannelCount; j++)
                        {
                            colors[j][i] = new Vector4(c[j][i].R, c[j][i].G, c[j][i].B, c[j][i].A);
                        }
                    }
                    else
                    {
                        colors[0][i] = new Vector4(1, 1, 1, 1);
                    }

                }
            }

            mesh.Vertices = verts;
            mesh.Normals = norms;
            mesh.Tangents = tangents;
            mesh.Binormals = binormals;
            mesh.UV = uv;
            mesh.Colors = colors;

            var aindices = amesh.GetIndices();

            var indices = new uint[aindices.Length];

            for (int i = 0; i < aindices.Length; i++)
            {
                indices[i] = (uint)aindices[i];
            }

            mesh.Indices = indices;

            return mesh;
        }