コード例 #1
0
        /// <summary>
        /// Add array of vertices to the combined mesh.
        /// </summary>
        /// <param name="vertices">Vertices array to add.</param>
        /// <param name="indexes">Draw order / indexes array.</param>
        /// <param name="material">Material to use with the vertices.</param>
        public void AddVertices(VertexType[] vertices, ushort[] indexes, Materials.MaterialAPI material)
        {
            // sanity check - if build was called assert
            if (_wasBuilt)
            {
                throw new Exceptions.InvalidActionException("Cannot add vertices to Combined Mesh Entity after it was built!");
            }

            // get the combined chunk to add these vertices to
            CombinedMeshesPart combinedPart = GetCombinedPart(material);

            // add vertices to combined part
            combinedPart.Vertices.AddRange(vertices);
            foreach (var vertex in vertices)
            {
                _allPoints.Add(GetPosition(vertex));
            }

            // set indexes
            combinedPart.PushIndexes(indexes);

            // increase index offset in combined part
            combinedPart.IndexOffset += vertices.Length;

            // update primitives count
            combinedPart.PrimitiveCount += indexes.Length / 3;
        }
コード例 #2
0
        /// <summary>
        /// Get combined mesh part from material.
        /// </summary>
        /// <param name="material">Material to get combined part for.</param>
        /// <returns>Combined mesh part.</returns>
        private CombinedMeshesPart GetCombinedPart(Materials.MaterialAPI material)
        {
            // try to get from existing parts and if not found create it
            CombinedMeshesPart combinedPart;

            if (!_parts.TryGetValue(material, out combinedPart))
            {
                combinedPart     = new CombinedMeshesPart();
                _parts[material] = combinedPart;
            }

            // return combined part
            return(combinedPart);
        }
コード例 #3
0
        /// <summary>
        /// Add a model mesh to the combined mesh.
        /// </summary>
        /// <param name="mesh">Mesh to add.</param>
        /// <param name="transform">World transformations.</param>
        /// <param name="material">Optional material to use instead of the mesh default materials.</param>
        public void AddModelMesh(ModelMesh mesh, Matrix transform, Materials.MaterialAPI material = null)
        {
            // sanity check - if build was called assert
            if (_wasBuilt)
            {
                throw new Exceptions.InvalidActionException("Cannot add meshes to Combined Mesh Entity after it was built!");
            }

            // did we get material override to set?
            bool externalMaterial = material != null;

            // iterate mesh parts
            foreach (var meshPart in mesh.MeshParts)
            {
                // if we didn't get external material to use, get material from mesh part.
                if (!externalMaterial)
                {
                    material = meshPart.GetMaterial();
                }

                // get the combined chunk to add this meshpart to
                CombinedMeshesPart combinedPart = GetCombinedPart(material);

                // make sure its not readonly
                if (meshPart.VertexBuffer.BufferUsage == BufferUsage.WriteOnly ||
                    meshPart.IndexBuffer.BufferUsage == BufferUsage.WriteOnly)
                {
                    throw new Exceptions.InvalidValueException("Cannot add mesh with write-only buffers to Combined Mesh!");
                }

                // make sure vertex buffer uses position-normal-texture
                if (meshPart.VertexBuffer.VertexDeclaration.VertexStride < 8)
                {
                    throw new Exceptions.InvalidValueException("Combined meshes can only use vertex buffers with position, normal and texture!");
                }

                // get vertex buffer parameters
                int vertexStride     = meshPart.VertexBuffer.VertexDeclaration.VertexStride;
                int vertexBufferSize = meshPart.NumVertices * vertexStride;

                // get vertex data as float
                float[] vertexData = new float[vertexBufferSize / sizeof(float)];
                meshPart.VertexBuffer.GetData <float>(vertexData);

                // iterate through vertices and add them
                int verticesInPart = 0;
                for (int i = 0; i < vertexBufferSize / sizeof(float); i += vertexStride / sizeof(float))
                {
                    // get curr position with transformations
                    Vector3 currPosition = Vector3.Transform(new Vector3(vertexData[i], vertexData[i + 1], vertexData[i + 2]), transform);

                    // get other vertex properties based on type and add to vertices buffer
                    switch (_vtype)
                    {
                    case VertexTypes.VertexPosition:
                    {
                        // add to buffer
                        var vertexToAdd = new VertexPosition(currPosition);
                        combinedPart.Vertices.Add(ToVertexType(vertexToAdd));
                        break;
                    }

                    case VertexTypes.VertexPositionColor:
                    {
                        // get color
                        Color currColor = new Color(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5], vertexData[i + 6]);

                        // add to buffer
                        var vertexToAdd = new VertexPositionColor(currPosition, currColor);
                        combinedPart.Vertices.Add(ToVertexType(vertexToAdd));
                        break;
                    }

                    case VertexTypes.VertexPositionNormalTexture:
                    {
                        // get normal
                        Vector3 normal = new Vector3(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5]);
                        normal = Vector3.Normalize(Vector3.TransformNormal(normal, transform));

                        // get texture coords
                        Vector2 textcoords = new Vector2(vertexData[i + 6], vertexData[i + 7]);

                        // add to buffer
                        var vertexToAdd = new VertexPositionNormalTexture(currPosition, normal, textcoords);
                        combinedPart.Vertices.Add(ToVertexType(vertexToAdd));
                        break;
                    }

                    case VertexTypes.VertexPositionNormalTangentTexture:
                    {
                        // get normal
                        Vector3 normal = new Vector3(vertexData[i + 3], vertexData[i + 4], vertexData[i + 5]);
                        normal = Vector3.Normalize(Vector3.TransformNormal(normal, transform));

                        // get tangent
                        Vector3 tangent = new Vector3(vertexData[i + 6], vertexData[i + 7], vertexData[i + 8]);

                        // get binormal
                        Vector3 binormal = new Vector3(vertexData[i + 9], vertexData[i + 10], vertexData[i + 11]);

                        // get texture coords
                        Vector2 textcoords = new Vector2(vertexData[i + 12], vertexData[i + 13]);

                        // add to buffer
                        var vertexToAdd = new VertexPositionNormalTangentTexture(currPosition, normal, textcoords, tangent, binormal);
                        combinedPart.Vertices.Add(ToVertexType(vertexToAdd));
                        break;
                    }

                    case VertexTypes.VertexPositionTexture:
                    {
                        // get texture coords
                        Vector2 textcoords = new Vector2(vertexData[i + 3], vertexData[i + 4]);

                        // add to buffer
                        var vertexToAdd = new VertexPositionTexture(currPosition, textcoords);
                        combinedPart.Vertices.Add(ToVertexType(vertexToAdd));
                        break;
                    }

                    default:
                        throw new Exceptions.InternalError("Forgot to implement type support?");
                    }

                    // add to temp list of all points and increase vertices count
                    _allPoints.Add(currPosition);
                    verticesInPart++;
                }

                // set indexes
                ushort[] drawOrder = new ushort[meshPart.IndexBuffer.IndexCount];
                meshPart.IndexBuffer.GetData <ushort>(drawOrder);
                combinedPart.PushIndexes(drawOrder);

                // increase indexes offset
                combinedPart.IndexOffset += verticesInPart;

                // increase primitives count
                combinedPart.PrimitiveCount += meshPart.PrimitiveCount;
            }
        }